trurwsuieghfdskg
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
Manifest-Version: 1.0
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.mojang.blaze3d;
|
||||
|
||||
import com.mojang.blaze3d.pipeline.RenderCall;
|
||||
import com.mojang.blaze3d.pipeline.RenderPipeline;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class Blaze3D {
|
||||
public static void process(RenderPipeline p_166119_, float p_166120_) {
|
||||
ConcurrentLinkedQueue<RenderCall> concurrentlinkedqueue = p_166119_.getRecordingQueue();
|
||||
}
|
||||
|
||||
public static void render(RenderPipeline p_166122_, float p_166123_) {
|
||||
ConcurrentLinkedQueue<RenderCall> concurrentlinkedqueue = p_166122_.getProcessedQueue();
|
||||
}
|
||||
|
||||
public static void youJustLostTheGame() {
|
||||
MemoryUtil.memSet(0L, 0, 1L);
|
||||
}
|
||||
|
||||
public static double getTime() {
|
||||
return GLFW.glfwGetTime();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.mojang.blaze3d;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import javax.annotation.meta.TypeQualifierDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@TypeQualifierDefault({ElementType.TYPE, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public @interface DontObfuscate {
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.mojang.blaze3d;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.meta.TypeQualifierDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@Nonnull
|
||||
@TypeQualifierDefault({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public @interface FieldsAreNonnullByDefault {
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.mojang.blaze3d;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.meta.TypeQualifierDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@Nonnull
|
||||
@TypeQualifierDefault({ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public @interface MethodsReturnNonnullByDefault {
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
package com.mojang.blaze3d.audio;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import net.minecraft.client.sounds.AudioStream;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.openal.AL10;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class Channel {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final int QUEUED_BUFFER_COUNT = 4;
|
||||
public static final int BUFFER_DURATION_SECONDS = 1;
|
||||
private final int source;
|
||||
private final AtomicBoolean initialized = new AtomicBoolean(true);
|
||||
private int streamingBufferSize = 16384;
|
||||
@Nullable
|
||||
private AudioStream stream;
|
||||
|
||||
@Nullable
|
||||
static Channel create() {
|
||||
int[] aint = new int[1];
|
||||
AL10.alGenSources(aint);
|
||||
return OpenAlUtil.checkALError("Allocate new source") ? null : new Channel(aint[0]);
|
||||
}
|
||||
|
||||
private Channel(int p_83648_) {
|
||||
this.source = p_83648_;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
if (this.initialized.compareAndSet(true, false)) {
|
||||
AL10.alSourceStop(this.source);
|
||||
OpenAlUtil.checkALError("Stop");
|
||||
if (this.stream != null) {
|
||||
try {
|
||||
this.stream.close();
|
||||
} catch (IOException ioexception) {
|
||||
LOGGER.error("Failed to close audio stream", (Throwable)ioexception);
|
||||
}
|
||||
|
||||
this.removeProcessedBuffers();
|
||||
this.stream = null;
|
||||
}
|
||||
|
||||
AL10.alDeleteSources(new int[]{this.source});
|
||||
OpenAlUtil.checkALError("Cleanup");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void play() {
|
||||
AL10.alSourcePlay(this.source);
|
||||
}
|
||||
|
||||
private int getState() {
|
||||
return !this.initialized.get() ? 4116 : AL10.alGetSourcei(this.source, 4112);
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
if (this.getState() == 4114) {
|
||||
AL10.alSourcePause(this.source);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void unpause() {
|
||||
if (this.getState() == 4115) {
|
||||
AL10.alSourcePlay(this.source);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if (this.initialized.get()) {
|
||||
AL10.alSourceStop(this.source);
|
||||
OpenAlUtil.checkALError("Stop");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean playing() {
|
||||
return this.getState() == 4114;
|
||||
}
|
||||
|
||||
public boolean stopped() {
|
||||
return this.getState() == 4116;
|
||||
}
|
||||
|
||||
public void setSelfPosition(Vec3 p_83655_) {
|
||||
AL10.alSourcefv(this.source, 4100, new float[]{(float)p_83655_.x, (float)p_83655_.y, (float)p_83655_.z});
|
||||
}
|
||||
|
||||
public void setPitch(float p_83651_) {
|
||||
AL10.alSourcef(this.source, 4099, p_83651_);
|
||||
}
|
||||
|
||||
public void setLooping(boolean p_83664_) {
|
||||
AL10.alSourcei(this.source, 4103, p_83664_ ? 1 : 0);
|
||||
}
|
||||
|
||||
public void setVolume(float p_83667_) {
|
||||
AL10.alSourcef(this.source, 4106, p_83667_);
|
||||
}
|
||||
|
||||
public void disableAttenuation() {
|
||||
AL10.alSourcei(this.source, 53248, 0);
|
||||
}
|
||||
|
||||
public void linearAttenuation(float p_83674_) {
|
||||
AL10.alSourcei(this.source, 53248, 53251);
|
||||
AL10.alSourcef(this.source, 4131, p_83674_);
|
||||
AL10.alSourcef(this.source, 4129, 1.0F);
|
||||
AL10.alSourcef(this.source, 4128, 0.0F);
|
||||
}
|
||||
|
||||
public void setRelative(boolean p_83671_) {
|
||||
AL10.alSourcei(this.source, 514, p_83671_ ? 1 : 0);
|
||||
}
|
||||
|
||||
public void attachStaticBuffer(SoundBuffer p_83657_) {
|
||||
p_83657_.getAlBuffer().ifPresent((p_83676_) -> {
|
||||
AL10.alSourcei(this.source, 4105, p_83676_);
|
||||
});
|
||||
}
|
||||
|
||||
public void attachBufferStream(AudioStream p_83659_) {
|
||||
this.stream = p_83659_;
|
||||
AudioFormat audioformat = p_83659_.getFormat();
|
||||
this.streamingBufferSize = calculateBufferSize(audioformat, 1);
|
||||
this.pumpBuffers(4);
|
||||
}
|
||||
|
||||
private static int calculateBufferSize(AudioFormat p_83661_, int p_83662_) {
|
||||
return (int)((float)(p_83662_ * p_83661_.getSampleSizeInBits()) / 8.0F * (float)p_83661_.getChannels() * p_83661_.getSampleRate());
|
||||
}
|
||||
|
||||
private void pumpBuffers(int p_83653_) {
|
||||
if (this.stream != null) {
|
||||
try {
|
||||
for(int i = 0; i < p_83653_; ++i) {
|
||||
ByteBuffer bytebuffer = this.stream.read(this.streamingBufferSize);
|
||||
if (bytebuffer != null) {
|
||||
(new SoundBuffer(bytebuffer, this.stream.getFormat())).releaseAlBuffer().ifPresent((p_83669_) -> {
|
||||
AL10.alSourceQueueBuffers(this.source, new int[]{p_83669_});
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (IOException ioexception) {
|
||||
LOGGER.error("Failed to read from audio stream", (Throwable)ioexception);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void updateStream() {
|
||||
if (this.stream != null) {
|
||||
int i = this.removeProcessedBuffers();
|
||||
this.pumpBuffers(i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private int removeProcessedBuffers() {
|
||||
int i = AL10.alGetSourcei(this.source, 4118);
|
||||
if (i > 0) {
|
||||
int[] aint = new int[i];
|
||||
AL10.alSourceUnqueueBuffers(this.source, aint);
|
||||
OpenAlUtil.checkALError("Unqueue buffers");
|
||||
AL10.alDeleteBuffers(aint);
|
||||
OpenAlUtil.checkALError("Remove processed buffers");
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
package com.mojang.blaze3d.audio;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.OptionalLong;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.openal.AL;
|
||||
import org.lwjgl.openal.AL10;
|
||||
import org.lwjgl.openal.ALC;
|
||||
import org.lwjgl.openal.ALC10;
|
||||
import org.lwjgl.openal.ALC11;
|
||||
import org.lwjgl.openal.ALCCapabilities;
|
||||
import org.lwjgl.openal.ALCapabilities;
|
||||
import org.lwjgl.openal.ALUtil;
|
||||
import org.lwjgl.openal.SOFTHRTF;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class Library {
|
||||
static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final int NO_DEVICE = 0;
|
||||
private static final int DEFAULT_CHANNEL_COUNT = 30;
|
||||
private long currentDevice;
|
||||
private long context;
|
||||
private boolean supportsDisconnections;
|
||||
@Nullable
|
||||
private String defaultDeviceName;
|
||||
private static final Library.ChannelPool EMPTY = new Library.ChannelPool() {
|
||||
@Nullable
|
||||
public Channel acquire() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean release(Channel p_83708_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
}
|
||||
|
||||
public int getMaxCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getUsedCount() {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
private Library.ChannelPool staticChannels = EMPTY;
|
||||
private Library.ChannelPool streamingChannels = EMPTY;
|
||||
private final Listener listener = new Listener();
|
||||
|
||||
public Library() {
|
||||
this.defaultDeviceName = getDefaultDeviceName();
|
||||
}
|
||||
|
||||
public void init(@Nullable String p_231085_, boolean p_231086_) {
|
||||
this.currentDevice = openDeviceOrFallback(p_231085_);
|
||||
this.supportsDisconnections = ALC10.alcIsExtensionPresent(this.currentDevice, "ALC_EXT_disconnect");
|
||||
ALCCapabilities alccapabilities = ALC.createCapabilities(this.currentDevice);
|
||||
if (OpenAlUtil.checkALCError(this.currentDevice, "Get capabilities")) {
|
||||
throw new IllegalStateException("Failed to get OpenAL capabilities");
|
||||
} else if (!alccapabilities.OpenALC11) {
|
||||
throw new IllegalStateException("OpenAL 1.1 not supported");
|
||||
} else {
|
||||
this.setHrtf(alccapabilities.ALC_SOFT_HRTF && p_231086_);
|
||||
this.context = ALC10.alcCreateContext(this.currentDevice, (IntBuffer)null);
|
||||
ALC10.alcMakeContextCurrent(this.context);
|
||||
int i = this.getChannelCount();
|
||||
int j = Mth.clamp((int)Mth.sqrt((float)i), 2, 8);
|
||||
int k = Mth.clamp(i - j, 8, 255);
|
||||
this.staticChannels = new Library.CountingChannelPool(k);
|
||||
this.streamingChannels = new Library.CountingChannelPool(j);
|
||||
ALCapabilities alcapabilities = AL.createCapabilities(alccapabilities);
|
||||
OpenAlUtil.checkALError("Initialization");
|
||||
if (!alcapabilities.AL_EXT_source_distance_model) {
|
||||
throw new IllegalStateException("AL_EXT_source_distance_model is not supported");
|
||||
} else {
|
||||
AL10.alEnable(512);
|
||||
if (!alcapabilities.AL_EXT_LINEAR_DISTANCE) {
|
||||
throw new IllegalStateException("AL_EXT_LINEAR_DISTANCE is not supported");
|
||||
} else {
|
||||
OpenAlUtil.checkALError("Enable per-source distance models");
|
||||
LOGGER.info("OpenAL initialized on device {}", (Object)this.getCurrentDeviceName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setHrtf(boolean p_242278_) {
|
||||
int i = ALC10.alcGetInteger(this.currentDevice, 6548);
|
||||
if (i > 0) {
|
||||
try (MemoryStack memorystack = MemoryStack.stackPush()) {
|
||||
IntBuffer intbuffer = memorystack.callocInt(10).put(6546).put(p_242278_ ? 1 : 0).put(6550).put(0).put(0).flip();
|
||||
if (!SOFTHRTF.alcResetDeviceSOFT(this.currentDevice, intbuffer)) {
|
||||
LOGGER.warn("Failed to reset device: {}", (Object)ALC10.alcGetString(this.currentDevice, ALC10.alcGetError(this.currentDevice)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private int getChannelCount() {
|
||||
try (MemoryStack memorystack = MemoryStack.stackPush()) {
|
||||
int i = ALC10.alcGetInteger(this.currentDevice, 4098);
|
||||
if (OpenAlUtil.checkALCError(this.currentDevice, "Get attributes size")) {
|
||||
throw new IllegalStateException("Failed to get OpenAL attributes");
|
||||
}
|
||||
|
||||
IntBuffer intbuffer = memorystack.mallocInt(i);
|
||||
ALC10.alcGetIntegerv(this.currentDevice, 4099, intbuffer);
|
||||
if (OpenAlUtil.checkALCError(this.currentDevice, "Get attributes")) {
|
||||
throw new IllegalStateException("Failed to get OpenAL attributes");
|
||||
}
|
||||
|
||||
int j = 0;
|
||||
|
||||
while(j < i) {
|
||||
int k = intbuffer.get(j++);
|
||||
if (k == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
int l = intbuffer.get(j++);
|
||||
if (k == 4112) {
|
||||
return l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 30;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getDefaultDeviceName() {
|
||||
if (!ALC10.alcIsExtensionPresent(0L, "ALC_ENUMERATE_ALL_EXT")) {
|
||||
return null;
|
||||
} else {
|
||||
ALUtil.getStringList(0L, 4115);
|
||||
return ALC10.alcGetString(0L, 4114);
|
||||
}
|
||||
}
|
||||
|
||||
public String getCurrentDeviceName() {
|
||||
String s = ALC10.alcGetString(this.currentDevice, 4115);
|
||||
if (s == null) {
|
||||
s = ALC10.alcGetString(this.currentDevice, 4101);
|
||||
}
|
||||
|
||||
if (s == null) {
|
||||
s = "Unknown";
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
public synchronized boolean hasDefaultDeviceChanged() {
|
||||
String s = getDefaultDeviceName();
|
||||
if (Objects.equals(this.defaultDeviceName, s)) {
|
||||
return false;
|
||||
} else {
|
||||
this.defaultDeviceName = s;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static long openDeviceOrFallback(@Nullable String p_193473_) {
|
||||
OptionalLong optionallong = OptionalLong.empty();
|
||||
if (p_193473_ != null) {
|
||||
optionallong = tryOpenDevice(p_193473_);
|
||||
}
|
||||
|
||||
if (optionallong.isEmpty()) {
|
||||
optionallong = tryOpenDevice(getDefaultDeviceName());
|
||||
}
|
||||
|
||||
if (optionallong.isEmpty()) {
|
||||
optionallong = tryOpenDevice((String)null);
|
||||
}
|
||||
|
||||
if (optionallong.isEmpty()) {
|
||||
throw new IllegalStateException("Failed to open OpenAL device");
|
||||
} else {
|
||||
return optionallong.getAsLong();
|
||||
}
|
||||
}
|
||||
|
||||
private static OptionalLong tryOpenDevice(@Nullable String p_193476_) {
|
||||
long i = ALC10.alcOpenDevice(p_193476_);
|
||||
return i != 0L && !OpenAlUtil.checkALCError(i, "Open device") ? OptionalLong.of(i) : OptionalLong.empty();
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
this.staticChannels.cleanup();
|
||||
this.streamingChannels.cleanup();
|
||||
ALC10.alcDestroyContext(this.context);
|
||||
if (this.currentDevice != 0L) {
|
||||
ALC10.alcCloseDevice(this.currentDevice);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Listener getListener() {
|
||||
return this.listener;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Channel acquireChannel(Library.Pool p_83698_) {
|
||||
return (p_83698_ == Library.Pool.STREAMING ? this.streamingChannels : this.staticChannels).acquire();
|
||||
}
|
||||
|
||||
public void releaseChannel(Channel p_83696_) {
|
||||
if (!this.staticChannels.release(p_83696_) && !this.streamingChannels.release(p_83696_)) {
|
||||
throw new IllegalStateException("Tried to release unknown channel");
|
||||
}
|
||||
}
|
||||
|
||||
public String getDebugString() {
|
||||
return String.format(Locale.ROOT, "Sounds: %d/%d + %d/%d", this.staticChannels.getUsedCount(), this.staticChannels.getMaxCount(), this.streamingChannels.getUsedCount(), this.streamingChannels.getMaxCount());
|
||||
}
|
||||
|
||||
public List<String> getAvailableSoundDevices() {
|
||||
List<String> list = ALUtil.getStringList(0L, 4115);
|
||||
return list == null ? Collections.emptyList() : list;
|
||||
}
|
||||
|
||||
public boolean isCurrentDeviceDisconnected() {
|
||||
return this.supportsDisconnections && ALC11.alcGetInteger(this.currentDevice, 787) == 0;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
interface ChannelPool {
|
||||
@Nullable
|
||||
Channel acquire();
|
||||
|
||||
boolean release(Channel p_83712_);
|
||||
|
||||
void cleanup();
|
||||
|
||||
int getMaxCount();
|
||||
|
||||
int getUsedCount();
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class CountingChannelPool implements Library.ChannelPool {
|
||||
private final int limit;
|
||||
private final Set<Channel> activeChannels = Sets.newIdentityHashSet();
|
||||
|
||||
public CountingChannelPool(int p_83716_) {
|
||||
this.limit = p_83716_;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Channel acquire() {
|
||||
if (this.activeChannels.size() >= this.limit) {
|
||||
if (SharedConstants.IS_RUNNING_IN_IDE) {
|
||||
Library.LOGGER.warn("Maximum sound pool size {} reached", (int)this.limit);
|
||||
}
|
||||
|
||||
return null;
|
||||
} else {
|
||||
Channel channel = Channel.create();
|
||||
if (channel != null) {
|
||||
this.activeChannels.add(channel);
|
||||
}
|
||||
|
||||
return channel;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean release(Channel p_83719_) {
|
||||
if (!this.activeChannels.remove(p_83719_)) {
|
||||
return false;
|
||||
} else {
|
||||
p_83719_.destroy();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
this.activeChannels.forEach(Channel::destroy);
|
||||
this.activeChannels.clear();
|
||||
}
|
||||
|
||||
public int getMaxCount() {
|
||||
return this.limit;
|
||||
}
|
||||
|
||||
public int getUsedCount() {
|
||||
return this.activeChannels.size();
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum Pool {
|
||||
STATIC,
|
||||
STREAMING;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.mojang.blaze3d.audio;
|
||||
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.joml.Vector3f;
|
||||
import org.lwjgl.openal.AL10;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class Listener {
|
||||
private float gain = 1.0F;
|
||||
private Vec3 position = Vec3.ZERO;
|
||||
|
||||
public void setListenerPosition(Vec3 p_83740_) {
|
||||
this.position = p_83740_;
|
||||
AL10.alListener3f(4100, (float)p_83740_.x, (float)p_83740_.y, (float)p_83740_.z);
|
||||
}
|
||||
|
||||
public Vec3 getListenerPosition() {
|
||||
return this.position;
|
||||
}
|
||||
|
||||
public void setListenerOrientation(Vector3f p_254324_, Vector3f p_253810_) {
|
||||
AL10.alListenerfv(4111, new float[]{p_254324_.x(), p_254324_.y(), p_254324_.z(), p_253810_.x(), p_253810_.y(), p_253810_.z()});
|
||||
}
|
||||
|
||||
public void setGain(float p_83738_) {
|
||||
AL10.alListenerf(4106, p_83738_);
|
||||
this.gain = p_83738_;
|
||||
}
|
||||
|
||||
public float getGain() {
|
||||
return this.gain;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
this.setListenerPosition(Vec3.ZERO);
|
||||
this.setListenerOrientation(new Vector3f(0.0F, 0.0F, -1.0F), new Vector3f(0.0F, 1.0F, 0.0F));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
package com.mojang.blaze3d.audio;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.List;
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import net.minecraft.client.sounds.AudioStream;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.stb.STBVorbis;
|
||||
import org.lwjgl.stb.STBVorbisAlloc;
|
||||
import org.lwjgl.stb.STBVorbisInfo;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class OggAudioStream implements AudioStream {
|
||||
private static final int EXPECTED_MAX_FRAME_SIZE = 8192;
|
||||
private long handle;
|
||||
private final AudioFormat audioFormat;
|
||||
private final InputStream input;
|
||||
private ByteBuffer buffer = MemoryUtil.memAlloc(8192);
|
||||
|
||||
public OggAudioStream(InputStream p_83751_) throws IOException {
|
||||
this.input = p_83751_;
|
||||
this.buffer.limit(0);
|
||||
|
||||
try (MemoryStack memorystack = MemoryStack.stackPush()) {
|
||||
IntBuffer intbuffer = memorystack.mallocInt(1);
|
||||
IntBuffer intbuffer1 = memorystack.mallocInt(1);
|
||||
|
||||
while(this.handle == 0L) {
|
||||
if (!this.refillFromStream()) {
|
||||
throw new IOException("Failed to find Ogg header");
|
||||
}
|
||||
|
||||
int i = this.buffer.position();
|
||||
this.buffer.position(0);
|
||||
this.handle = STBVorbis.stb_vorbis_open_pushdata(this.buffer, intbuffer, intbuffer1, (STBVorbisAlloc)null);
|
||||
this.buffer.position(i);
|
||||
int j = intbuffer1.get(0);
|
||||
if (j == 1) {
|
||||
this.forwardBuffer();
|
||||
} else if (j != 0) {
|
||||
throw new IOException("Failed to read Ogg file " + j);
|
||||
}
|
||||
}
|
||||
|
||||
this.buffer.position(this.buffer.position() + intbuffer.get(0));
|
||||
STBVorbisInfo stbvorbisinfo = STBVorbisInfo.mallocStack(memorystack);
|
||||
STBVorbis.stb_vorbis_get_info(this.handle, stbvorbisinfo);
|
||||
this.audioFormat = new AudioFormat((float)stbvorbisinfo.sample_rate(), 16, stbvorbisinfo.channels(), true, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean refillFromStream() throws IOException {
|
||||
int i = this.buffer.limit();
|
||||
int j = this.buffer.capacity() - i;
|
||||
if (j == 0) {
|
||||
return true;
|
||||
} else {
|
||||
byte[] abyte = new byte[j];
|
||||
int k = this.input.read(abyte);
|
||||
if (k == -1) {
|
||||
return false;
|
||||
} else {
|
||||
int l = this.buffer.position();
|
||||
this.buffer.limit(i + k);
|
||||
this.buffer.position(i);
|
||||
this.buffer.put(abyte, 0, k);
|
||||
this.buffer.position(l);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void forwardBuffer() {
|
||||
boolean flag = this.buffer.position() == 0;
|
||||
boolean flag1 = this.buffer.position() == this.buffer.limit();
|
||||
if (flag1 && !flag) {
|
||||
this.buffer.position(0);
|
||||
this.buffer.limit(0);
|
||||
} else {
|
||||
ByteBuffer bytebuffer = MemoryUtil.memAlloc(flag ? 2 * this.buffer.capacity() : this.buffer.capacity());
|
||||
bytebuffer.put(this.buffer);
|
||||
MemoryUtil.memFree(this.buffer);
|
||||
bytebuffer.flip();
|
||||
this.buffer = bytebuffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean readFrame(OggAudioStream.OutputConcat p_83756_) throws IOException {
|
||||
if (this.handle == 0L) {
|
||||
return false;
|
||||
} else {
|
||||
try (MemoryStack memorystack = MemoryStack.stackPush()) {
|
||||
PointerBuffer pointerbuffer = memorystack.mallocPointer(1);
|
||||
IntBuffer intbuffer = memorystack.mallocInt(1);
|
||||
IntBuffer intbuffer1 = memorystack.mallocInt(1);
|
||||
|
||||
while(true) {
|
||||
int i = STBVorbis.stb_vorbis_decode_frame_pushdata(this.handle, this.buffer, intbuffer, pointerbuffer, intbuffer1);
|
||||
this.buffer.position(this.buffer.position() + i);
|
||||
int j = STBVorbis.stb_vorbis_get_error(this.handle);
|
||||
if (j == 1) {
|
||||
this.forwardBuffer();
|
||||
if (!this.refillFromStream()) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (j != 0) {
|
||||
throw new IOException("Failed to read Ogg file " + j);
|
||||
}
|
||||
|
||||
int k = intbuffer1.get(0);
|
||||
if (k != 0) {
|
||||
int l = intbuffer.get(0);
|
||||
PointerBuffer pointerbuffer1 = pointerbuffer.getPointerBuffer(l);
|
||||
if (l == 1) {
|
||||
this.convertMono(pointerbuffer1.getFloatBuffer(0, k), p_83756_);
|
||||
return true;
|
||||
} else if (l != 2) {
|
||||
throw new IllegalStateException("Invalid number of channels: " + l);
|
||||
} else {
|
||||
this.convertStereo(pointerbuffer1.getFloatBuffer(0, k), pointerbuffer1.getFloatBuffer(1, k), p_83756_);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void convertMono(FloatBuffer p_83758_, OggAudioStream.OutputConcat p_83759_) {
|
||||
while(p_83758_.hasRemaining()) {
|
||||
p_83759_.put(p_83758_.get());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void convertStereo(FloatBuffer p_83761_, FloatBuffer p_83762_, OggAudioStream.OutputConcat p_83763_) {
|
||||
while(p_83761_.hasRemaining() && p_83762_.hasRemaining()) {
|
||||
p_83763_.put(p_83761_.get());
|
||||
p_83763_.put(p_83762_.get());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
if (this.handle != 0L) {
|
||||
STBVorbis.stb_vorbis_close(this.handle);
|
||||
this.handle = 0L;
|
||||
}
|
||||
|
||||
MemoryUtil.memFree(this.buffer);
|
||||
this.input.close();
|
||||
}
|
||||
|
||||
public AudioFormat getFormat() {
|
||||
return this.audioFormat;
|
||||
}
|
||||
|
||||
public ByteBuffer read(int p_83754_) throws IOException {
|
||||
OggAudioStream.OutputConcat oggaudiostream$outputconcat = new OggAudioStream.OutputConcat(p_83754_ + 8192);
|
||||
|
||||
while(this.readFrame(oggaudiostream$outputconcat) && oggaudiostream$outputconcat.byteCount < p_83754_) {
|
||||
}
|
||||
|
||||
return oggaudiostream$outputconcat.get();
|
||||
}
|
||||
|
||||
public ByteBuffer readAll() throws IOException {
|
||||
OggAudioStream.OutputConcat oggaudiostream$outputconcat = new OggAudioStream.OutputConcat(16384);
|
||||
|
||||
while(this.readFrame(oggaudiostream$outputconcat)) {
|
||||
}
|
||||
|
||||
return oggaudiostream$outputconcat.get();
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class OutputConcat {
|
||||
private final List<ByteBuffer> buffers = Lists.newArrayList();
|
||||
private final int bufferSize;
|
||||
int byteCount;
|
||||
private ByteBuffer currentBuffer;
|
||||
|
||||
public OutputConcat(int p_83773_) {
|
||||
this.bufferSize = p_83773_ + 1 & -2;
|
||||
this.createNewBuffer();
|
||||
}
|
||||
|
||||
private void createNewBuffer() {
|
||||
this.currentBuffer = BufferUtils.createByteBuffer(this.bufferSize);
|
||||
}
|
||||
|
||||
public void put(float p_83776_) {
|
||||
if (this.currentBuffer.remaining() == 0) {
|
||||
this.currentBuffer.flip();
|
||||
this.buffers.add(this.currentBuffer);
|
||||
this.createNewBuffer();
|
||||
}
|
||||
|
||||
int i = Mth.clamp((int)(p_83776_ * 32767.5F - 0.5F), -32768, 32767);
|
||||
this.currentBuffer.putShort((short)i);
|
||||
this.byteCount += 2;
|
||||
}
|
||||
|
||||
public ByteBuffer get() {
|
||||
this.currentBuffer.flip();
|
||||
if (this.buffers.isEmpty()) {
|
||||
return this.currentBuffer;
|
||||
} else {
|
||||
ByteBuffer bytebuffer = BufferUtils.createByteBuffer(this.byteCount);
|
||||
this.buffers.forEach(bytebuffer::put);
|
||||
bytebuffer.put(this.currentBuffer);
|
||||
bytebuffer.flip();
|
||||
return bytebuffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.mojang.blaze3d.audio;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.sound.sampled.AudioFormat.Encoding;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.openal.AL10;
|
||||
import org.lwjgl.openal.ALC10;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class OpenAlUtil {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
private static String alErrorToString(int p_83783_) {
|
||||
switch (p_83783_) {
|
||||
case 40961:
|
||||
return "Invalid name parameter.";
|
||||
case 40962:
|
||||
return "Invalid enumerated parameter value.";
|
||||
case 40963:
|
||||
return "Invalid parameter parameter value.";
|
||||
case 40964:
|
||||
return "Invalid operation.";
|
||||
case 40965:
|
||||
return "Unable to allocate memory.";
|
||||
default:
|
||||
return "An unrecognized error occurred.";
|
||||
}
|
||||
}
|
||||
|
||||
static boolean checkALError(String p_83788_) {
|
||||
int i = AL10.alGetError();
|
||||
if (i != 0) {
|
||||
LOGGER.error("{}: {}", p_83788_, alErrorToString(i));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static String alcErrorToString(int p_83792_) {
|
||||
switch (p_83792_) {
|
||||
case 40961:
|
||||
return "Invalid device.";
|
||||
case 40962:
|
||||
return "Invalid context.";
|
||||
case 40963:
|
||||
return "Illegal enum.";
|
||||
case 40964:
|
||||
return "Invalid value.";
|
||||
case 40965:
|
||||
return "Unable to allocate memory.";
|
||||
default:
|
||||
return "An unrecognized error occurred.";
|
||||
}
|
||||
}
|
||||
|
||||
static boolean checkALCError(long p_83785_, String p_83786_) {
|
||||
int i = ALC10.alcGetError(p_83785_);
|
||||
if (i != 0) {
|
||||
LOGGER.error("{}{}: {}", p_83786_, p_83785_, alcErrorToString(i));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static int audioFormatToOpenAl(AudioFormat p_83790_) {
|
||||
AudioFormat.Encoding encoding = p_83790_.getEncoding();
|
||||
int i = p_83790_.getChannels();
|
||||
int j = p_83790_.getSampleSizeInBits();
|
||||
if (encoding.equals(Encoding.PCM_UNSIGNED) || encoding.equals(Encoding.PCM_SIGNED)) {
|
||||
if (i == 1) {
|
||||
if (j == 8) {
|
||||
return 4352;
|
||||
}
|
||||
|
||||
if (j == 16) {
|
||||
return 4353;
|
||||
}
|
||||
} else if (i == 2) {
|
||||
if (j == 8) {
|
||||
return 4354;
|
||||
}
|
||||
|
||||
if (j == 16) {
|
||||
return 4355;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Invalid audio format: " + p_83790_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.mojang.blaze3d.audio;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.OptionalInt;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.openal.AL10;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class SoundBuffer {
|
||||
@Nullable
|
||||
private ByteBuffer data;
|
||||
private final AudioFormat format;
|
||||
private boolean hasAlBuffer;
|
||||
private int alBuffer;
|
||||
|
||||
public SoundBuffer(ByteBuffer p_83798_, AudioFormat p_83799_) {
|
||||
this.data = p_83798_;
|
||||
this.format = p_83799_;
|
||||
}
|
||||
|
||||
OptionalInt getAlBuffer() {
|
||||
if (!this.hasAlBuffer) {
|
||||
if (this.data == null) {
|
||||
return OptionalInt.empty();
|
||||
}
|
||||
|
||||
int i = OpenAlUtil.audioFormatToOpenAl(this.format);
|
||||
int[] aint = new int[1];
|
||||
AL10.alGenBuffers(aint);
|
||||
if (OpenAlUtil.checkALError("Creating buffer")) {
|
||||
return OptionalInt.empty();
|
||||
}
|
||||
|
||||
AL10.alBufferData(aint[0], i, this.data, (int)this.format.getSampleRate());
|
||||
if (OpenAlUtil.checkALError("Assigning buffer data")) {
|
||||
return OptionalInt.empty();
|
||||
}
|
||||
|
||||
this.alBuffer = aint[0];
|
||||
this.hasAlBuffer = true;
|
||||
this.data = null;
|
||||
}
|
||||
|
||||
return OptionalInt.of(this.alBuffer);
|
||||
}
|
||||
|
||||
public void discardAlBuffer() {
|
||||
if (this.hasAlBuffer) {
|
||||
AL10.alDeleteBuffers(new int[]{this.alBuffer});
|
||||
if (OpenAlUtil.checkALError("Deleting stream buffers")) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.hasAlBuffer = false;
|
||||
}
|
||||
|
||||
public OptionalInt releaseAlBuffer() {
|
||||
OptionalInt optionalint = this.getAlBuffer();
|
||||
this.hasAlBuffer = false;
|
||||
return optionalint;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
package com.mojang.blaze3d.audio;
|
||||
|
||||
import com.mojang.blaze3d.FieldsAreNonnullByDefault;
|
||||
import com.mojang.blaze3d.MethodsReturnNonnullByDefault;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.mojang.blaze3d.font;
|
||||
|
||||
import java.util.function.Function;
|
||||
import net.minecraft.client.gui.font.glyphs.BakedGlyph;
|
||||
import net.minecraft.client.gui.font.glyphs.EmptyGlyph;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface GlyphInfo {
|
||||
float getAdvance();
|
||||
|
||||
default float getAdvance(boolean p_83828_) {
|
||||
return this.getAdvance() + (p_83828_ ? this.getBoldOffset() : 0.0F);
|
||||
}
|
||||
|
||||
default float getBoldOffset() {
|
||||
return 1.0F;
|
||||
}
|
||||
|
||||
default float getShadowOffset() {
|
||||
return 1.0F;
|
||||
}
|
||||
|
||||
BakedGlyph bake(Function<SheetGlyphInfo, BakedGlyph> p_231088_);
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface SpaceGlyphInfo extends GlyphInfo {
|
||||
default BakedGlyph bake(Function<SheetGlyphInfo, BakedGlyph> p_231090_) {
|
||||
return EmptyGlyph.INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.mojang.blaze3d.font;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface GlyphProvider extends AutoCloseable {
|
||||
default void close() {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
default GlyphInfo getGlyph(int p_231091_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
IntSet getSupportedGlyphs();
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.mojang.blaze3d.font;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface SheetGlyphInfo {
|
||||
int getPixelWidth();
|
||||
|
||||
int getPixelHeight();
|
||||
|
||||
void upload(int p_231092_, int p_231093_);
|
||||
|
||||
boolean isColored();
|
||||
|
||||
float getOversample();
|
||||
|
||||
default float getLeft() {
|
||||
return this.getBearingX();
|
||||
}
|
||||
|
||||
default float getRight() {
|
||||
return this.getLeft() + (float)this.getPixelWidth() / this.getOversample();
|
||||
}
|
||||
|
||||
default float getUp() {
|
||||
return this.getBearingY();
|
||||
}
|
||||
|
||||
default float getDown() {
|
||||
return this.getUp() + (float)this.getPixelHeight() / this.getOversample();
|
||||
}
|
||||
|
||||
default float getBearingX() {
|
||||
return 0.0F;
|
||||
}
|
||||
|
||||
default float getBearingY() {
|
||||
return 3.0F;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.mojang.blaze3d.font;
|
||||
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSets;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.gui.font.providers.GlyphProviderDefinition;
|
||||
import net.minecraft.client.gui.font.providers.GlyphProviderType;
|
||||
import net.minecraft.util.ExtraCodecs;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class SpaceProvider implements GlyphProvider {
|
||||
private final Int2ObjectMap<GlyphInfo.SpaceGlyphInfo> glyphs;
|
||||
|
||||
public SpaceProvider(Map<Integer, Float> p_286456_) {
|
||||
this.glyphs = new Int2ObjectOpenHashMap<>(p_286456_.size());
|
||||
p_286456_.forEach((p_286113_, p_286114_) -> {
|
||||
this.glyphs.put(p_286113_.intValue(), () -> {
|
||||
return p_286114_;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public GlyphInfo getGlyph(int p_231105_) {
|
||||
return this.glyphs.get(p_231105_);
|
||||
}
|
||||
|
||||
public IntSet getSupportedGlyphs() {
|
||||
return IntSets.unmodifiable(this.glyphs.keySet());
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static record Definition(Map<Integer, Float> advances) implements GlyphProviderDefinition {
|
||||
public static final MapCodec<SpaceProvider.Definition> CODEC = RecordCodecBuilder.mapCodec((p_286766_) -> {
|
||||
return p_286766_.group(Codec.unboundedMap(ExtraCodecs.CODEPOINT, Codec.FLOAT).fieldOf("advances").forGetter(SpaceProvider.Definition::advances)).apply(p_286766_, SpaceProvider.Definition::new);
|
||||
});
|
||||
|
||||
public GlyphProviderType type() {
|
||||
return GlyphProviderType.SPACE;
|
||||
}
|
||||
|
||||
public Either<GlyphProviderDefinition.Loader, GlyphProviderDefinition.Reference> unpack() {
|
||||
GlyphProviderDefinition.Loader glyphproviderdefinition$loader = (p_286243_) -> {
|
||||
return new SpaceProvider(this.advances);
|
||||
};
|
||||
return Either.left(glyphproviderdefinition$loader);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
package com.mojang.blaze3d.font;
|
||||
|
||||
import com.mojang.blaze3d.platform.NativeImage;
|
||||
import it.unimi.dsi.fastutil.ints.IntArraySet;
|
||||
import it.unimi.dsi.fastutil.ints.IntCollection;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.IntStream;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.gui.font.glyphs.BakedGlyph;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.stb.STBTTFontinfo;
|
||||
import org.lwjgl.stb.STBTruetype;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class TrueTypeGlyphProvider implements GlyphProvider {
|
||||
@Nullable
|
||||
private ByteBuffer fontMemory;
|
||||
@Nullable
|
||||
private STBTTFontinfo font;
|
||||
final float oversample;
|
||||
private final IntSet skip = new IntArraySet();
|
||||
final float shiftX;
|
||||
final float shiftY;
|
||||
final float pointScale;
|
||||
final float ascent;
|
||||
|
||||
public TrueTypeGlyphProvider(ByteBuffer p_83846_, STBTTFontinfo p_83847_, float p_83848_, float p_83849_, float p_83850_, float p_83851_, String p_83852_) {
|
||||
this.fontMemory = p_83846_;
|
||||
this.font = p_83847_;
|
||||
this.oversample = p_83849_;
|
||||
p_83852_.codePoints().forEach(this.skip::add);
|
||||
this.shiftX = p_83850_ * p_83849_;
|
||||
this.shiftY = p_83851_ * p_83849_;
|
||||
this.pointScale = STBTruetype.stbtt_ScaleForPixelHeight(p_83847_, p_83848_ * p_83849_);
|
||||
|
||||
try (MemoryStack memorystack = MemoryStack.stackPush()) {
|
||||
IntBuffer intbuffer = memorystack.mallocInt(1);
|
||||
IntBuffer intbuffer1 = memorystack.mallocInt(1);
|
||||
IntBuffer intbuffer2 = memorystack.mallocInt(1);
|
||||
STBTruetype.stbtt_GetFontVMetrics(p_83847_, intbuffer, intbuffer1, intbuffer2);
|
||||
this.ascent = (float)intbuffer.get(0) * this.pointScale;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public GlyphInfo getGlyph(int p_231116_) {
|
||||
STBTTFontinfo stbttfontinfo = this.validateFontOpen();
|
||||
if (this.skip.contains(p_231116_)) {
|
||||
return null;
|
||||
} else {
|
||||
try (MemoryStack memorystack = MemoryStack.stackPush()) {
|
||||
int i = STBTruetype.stbtt_FindGlyphIndex(stbttfontinfo, p_231116_);
|
||||
if (i == 0) {
|
||||
return null;
|
||||
} else {
|
||||
IntBuffer intbuffer = memorystack.mallocInt(1);
|
||||
IntBuffer intbuffer1 = memorystack.mallocInt(1);
|
||||
IntBuffer intbuffer2 = memorystack.mallocInt(1);
|
||||
IntBuffer intbuffer3 = memorystack.mallocInt(1);
|
||||
IntBuffer intbuffer4 = memorystack.mallocInt(1);
|
||||
IntBuffer intbuffer5 = memorystack.mallocInt(1);
|
||||
STBTruetype.stbtt_GetGlyphHMetrics(stbttfontinfo, i, intbuffer4, intbuffer5);
|
||||
STBTruetype.stbtt_GetGlyphBitmapBoxSubpixel(stbttfontinfo, i, this.pointScale, this.pointScale, this.shiftX, this.shiftY, intbuffer, intbuffer1, intbuffer2, intbuffer3);
|
||||
float f = (float)intbuffer4.get(0) * this.pointScale;
|
||||
int j = intbuffer2.get(0) - intbuffer.get(0);
|
||||
int k = intbuffer3.get(0) - intbuffer1.get(0);
|
||||
return (GlyphInfo)(j > 0 && k > 0 ? new TrueTypeGlyphProvider.Glyph(intbuffer.get(0), intbuffer2.get(0), -intbuffer1.get(0), -intbuffer3.get(0), f, (float)intbuffer5.get(0) * this.pointScale, i) : (GlyphInfo.SpaceGlyphInfo)() -> {
|
||||
return f / this.oversample;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STBTTFontinfo validateFontOpen() {
|
||||
if (this.fontMemory != null && this.font != null) {
|
||||
return this.font;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Provider already closed");
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (this.font != null) {
|
||||
this.font.free();
|
||||
this.font = null;
|
||||
}
|
||||
|
||||
MemoryUtil.memFree(this.fontMemory);
|
||||
this.fontMemory = null;
|
||||
}
|
||||
|
||||
public IntSet getSupportedGlyphs() {
|
||||
return IntStream.range(0, 65535).filter((p_231118_) -> {
|
||||
return !this.skip.contains(p_231118_);
|
||||
}).collect(IntOpenHashSet::new, IntCollection::add, IntCollection::addAll);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class Glyph implements GlyphInfo {
|
||||
final int width;
|
||||
final int height;
|
||||
final float bearingX;
|
||||
final float bearingY;
|
||||
private final float advance;
|
||||
final int index;
|
||||
|
||||
Glyph(int p_83882_, int p_83883_, int p_83884_, int p_83885_, float p_83886_, float p_83887_, int p_83888_) {
|
||||
this.width = p_83883_ - p_83882_;
|
||||
this.height = p_83884_ - p_83885_;
|
||||
this.advance = p_83886_ / TrueTypeGlyphProvider.this.oversample;
|
||||
this.bearingX = (p_83887_ + (float)p_83882_ + TrueTypeGlyphProvider.this.shiftX) / TrueTypeGlyphProvider.this.oversample;
|
||||
this.bearingY = (TrueTypeGlyphProvider.this.ascent - (float)p_83884_ + TrueTypeGlyphProvider.this.shiftY) / TrueTypeGlyphProvider.this.oversample;
|
||||
this.index = p_83888_;
|
||||
}
|
||||
|
||||
public float getAdvance() {
|
||||
return this.advance;
|
||||
}
|
||||
|
||||
public BakedGlyph bake(Function<SheetGlyphInfo, BakedGlyph> p_231120_) {
|
||||
return p_231120_.apply(new SheetGlyphInfo() {
|
||||
public int getPixelWidth() {
|
||||
return Glyph.this.width;
|
||||
}
|
||||
|
||||
public int getPixelHeight() {
|
||||
return Glyph.this.height;
|
||||
}
|
||||
|
||||
public float getOversample() {
|
||||
return TrueTypeGlyphProvider.this.oversample;
|
||||
}
|
||||
|
||||
public float getBearingX() {
|
||||
return Glyph.this.bearingX;
|
||||
}
|
||||
|
||||
public float getBearingY() {
|
||||
return Glyph.this.bearingY;
|
||||
}
|
||||
|
||||
public void upload(int p_231126_, int p_231127_) {
|
||||
STBTTFontinfo stbttfontinfo = TrueTypeGlyphProvider.this.validateFontOpen();
|
||||
NativeImage nativeimage = new NativeImage(NativeImage.Format.LUMINANCE, Glyph.this.width, Glyph.this.height, false);
|
||||
nativeimage.copyFromFont(stbttfontinfo, Glyph.this.index, Glyph.this.width, Glyph.this.height, TrueTypeGlyphProvider.this.pointScale, TrueTypeGlyphProvider.this.pointScale, TrueTypeGlyphProvider.this.shiftX, TrueTypeGlyphProvider.this.shiftY, 0, 0);
|
||||
nativeimage.upload(0, p_231126_, p_231127_, 0, 0, Glyph.this.width, Glyph.this.height, false, true);
|
||||
}
|
||||
|
||||
public boolean isColored() {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
package com.mojang.blaze3d.font;
|
||||
|
||||
import com.mojang.blaze3d.FieldsAreNonnullByDefault;
|
||||
import com.mojang.blaze3d.MethodsReturnNonnullByDefault;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
@@ -0,0 +1,9 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
package com.mojang.blaze3d;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
@@ -0,0 +1,148 @@
|
||||
package com.mojang.blaze3d.pipeline;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.platform.TextureUtil;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class MainTarget extends RenderTarget {
|
||||
public static final int DEFAULT_WIDTH = 854;
|
||||
public static final int DEFAULT_HEIGHT = 480;
|
||||
static final MainTarget.Dimension DEFAULT_DIMENSIONS = new MainTarget.Dimension(854, 480);
|
||||
|
||||
public MainTarget(int p_166137_, int p_166138_) {
|
||||
super(true);
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
if (!RenderSystem.isOnRenderThread()) {
|
||||
RenderSystem.recordRenderCall(() -> {
|
||||
this.createFrameBuffer(p_166137_, p_166138_);
|
||||
});
|
||||
} else {
|
||||
this.createFrameBuffer(p_166137_, p_166138_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void createFrameBuffer(int p_166142_, int p_166143_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
MainTarget.Dimension maintarget$dimension = this.allocateAttachments(p_166142_, p_166143_);
|
||||
this.frameBufferId = GlStateManager.glGenFramebuffers();
|
||||
GlStateManager._glBindFramebuffer(36160, this.frameBufferId);
|
||||
GlStateManager._bindTexture(this.colorTextureId);
|
||||
GlStateManager._texParameter(3553, 10241, 9728);
|
||||
GlStateManager._texParameter(3553, 10240, 9728);
|
||||
GlStateManager._texParameter(3553, 10242, 33071);
|
||||
GlStateManager._texParameter(3553, 10243, 33071);
|
||||
GlStateManager._glFramebufferTexture2D(36160, 36064, 3553, this.colorTextureId, 0);
|
||||
GlStateManager._bindTexture(this.depthBufferId);
|
||||
GlStateManager._texParameter(3553, 34892, 0);
|
||||
GlStateManager._texParameter(3553, 10241, 9728);
|
||||
GlStateManager._texParameter(3553, 10240, 9728);
|
||||
GlStateManager._texParameter(3553, 10242, 33071);
|
||||
GlStateManager._texParameter(3553, 10243, 33071);
|
||||
GlStateManager._glFramebufferTexture2D(36160, 36096, 3553, this.depthBufferId, 0);
|
||||
GlStateManager._bindTexture(0);
|
||||
this.viewWidth = maintarget$dimension.width;
|
||||
this.viewHeight = maintarget$dimension.height;
|
||||
this.width = maintarget$dimension.width;
|
||||
this.height = maintarget$dimension.height;
|
||||
this.checkStatus();
|
||||
GlStateManager._glBindFramebuffer(36160, 0);
|
||||
}
|
||||
|
||||
private MainTarget.Dimension allocateAttachments(int p_166147_, int p_166148_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
this.colorTextureId = TextureUtil.generateTextureId();
|
||||
this.depthBufferId = TextureUtil.generateTextureId();
|
||||
MainTarget.AttachmentState maintarget$attachmentstate = MainTarget.AttachmentState.NONE;
|
||||
|
||||
for(MainTarget.Dimension maintarget$dimension : MainTarget.Dimension.listWithFallback(p_166147_, p_166148_)) {
|
||||
maintarget$attachmentstate = MainTarget.AttachmentState.NONE;
|
||||
if (this.allocateColorAttachment(maintarget$dimension)) {
|
||||
maintarget$attachmentstate = maintarget$attachmentstate.with(MainTarget.AttachmentState.COLOR);
|
||||
}
|
||||
|
||||
if (this.allocateDepthAttachment(maintarget$dimension)) {
|
||||
maintarget$attachmentstate = maintarget$attachmentstate.with(MainTarget.AttachmentState.DEPTH);
|
||||
}
|
||||
|
||||
if (maintarget$attachmentstate == MainTarget.AttachmentState.COLOR_DEPTH) {
|
||||
return maintarget$dimension;
|
||||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException("Unrecoverable GL_OUT_OF_MEMORY (allocated attachments = " + maintarget$attachmentstate.name() + ")");
|
||||
}
|
||||
|
||||
private boolean allocateColorAttachment(MainTarget.Dimension p_166140_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GlStateManager._getError();
|
||||
GlStateManager._bindTexture(this.colorTextureId);
|
||||
GlStateManager._texImage2D(3553, 0, 32856, p_166140_.width, p_166140_.height, 0, 6408, 5121, (IntBuffer)null);
|
||||
return GlStateManager._getError() != 1285;
|
||||
}
|
||||
|
||||
private boolean allocateDepthAttachment(MainTarget.Dimension p_166145_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GlStateManager._getError();
|
||||
GlStateManager._bindTexture(this.depthBufferId);
|
||||
GlStateManager._texImage2D(3553, 0, 6402, p_166145_.width, p_166145_.height, 0, 6402, 5126, (IntBuffer)null);
|
||||
return GlStateManager._getError() != 1285;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static enum AttachmentState {
|
||||
NONE,
|
||||
COLOR,
|
||||
DEPTH,
|
||||
COLOR_DEPTH;
|
||||
|
||||
private static final MainTarget.AttachmentState[] VALUES = values();
|
||||
|
||||
MainTarget.AttachmentState with(MainTarget.AttachmentState p_166164_) {
|
||||
return VALUES[this.ordinal() | p_166164_.ordinal()];
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class Dimension {
|
||||
public final int width;
|
||||
public final int height;
|
||||
|
||||
Dimension(int p_166171_, int p_166172_) {
|
||||
this.width = p_166171_;
|
||||
this.height = p_166172_;
|
||||
}
|
||||
|
||||
static List<MainTarget.Dimension> listWithFallback(int p_166174_, int p_166175_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
int i = RenderSystem.maxSupportedTextureSize();
|
||||
return p_166174_ > 0 && p_166174_ <= i && p_166175_ > 0 && p_166175_ <= i ? ImmutableList.of(new MainTarget.Dimension(p_166174_, p_166175_), MainTarget.DEFAULT_DIMENSIONS) : ImmutableList.of(MainTarget.DEFAULT_DIMENSIONS);
|
||||
}
|
||||
|
||||
public boolean equals(Object p_166177_) {
|
||||
if (this == p_166177_) {
|
||||
return true;
|
||||
} else if (p_166177_ != null && this.getClass() == p_166177_.getClass()) {
|
||||
MainTarget.Dimension maintarget$dimension = (MainTarget.Dimension)p_166177_;
|
||||
return this.width == maintarget$dimension.width && this.height == maintarget$dimension.height;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.width, this.height);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.width + "x" + this.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.mojang.blaze3d.pipeline;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface RenderCall {
|
||||
void execute();
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.mojang.blaze3d.pipeline;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RenderPipeline {
|
||||
private final List<ConcurrentLinkedQueue<RenderCall>> renderCalls = ImmutableList.of(new ConcurrentLinkedQueue<>(), new ConcurrentLinkedQueue<>(), new ConcurrentLinkedQueue<>(), new ConcurrentLinkedQueue<>());
|
||||
private volatile boolean isRecording;
|
||||
private volatile int recordingBuffer;
|
||||
private volatile boolean isProcessing;
|
||||
private volatile int processedBuffer;
|
||||
private volatile int renderingBuffer;
|
||||
|
||||
public RenderPipeline() {
|
||||
this.recordingBuffer = this.processedBuffer = this.renderingBuffer + 1;
|
||||
}
|
||||
|
||||
public boolean canBeginRecording() {
|
||||
return !this.isRecording && this.recordingBuffer == this.processedBuffer;
|
||||
}
|
||||
|
||||
public boolean beginRecording() {
|
||||
if (this.isRecording) {
|
||||
throw new RuntimeException("ALREADY RECORDING !!!");
|
||||
} else if (this.canBeginRecording()) {
|
||||
this.recordingBuffer = (this.processedBuffer + 1) % this.renderCalls.size();
|
||||
this.isRecording = true;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void recordRenderCall(RenderCall p_166184_) {
|
||||
if (!this.isRecording) {
|
||||
throw new RuntimeException("NOT RECORDING !!!");
|
||||
} else {
|
||||
ConcurrentLinkedQueue<RenderCall> concurrentlinkedqueue = this.getRecordingQueue();
|
||||
concurrentlinkedqueue.add(p_166184_);
|
||||
}
|
||||
}
|
||||
|
||||
public void endRecording() {
|
||||
if (this.isRecording) {
|
||||
this.isRecording = false;
|
||||
} else {
|
||||
throw new RuntimeException("NOT RECORDING !!!");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canBeginProcessing() {
|
||||
return !this.isProcessing && this.recordingBuffer != this.processedBuffer;
|
||||
}
|
||||
|
||||
public boolean beginProcessing() {
|
||||
if (this.isProcessing) {
|
||||
throw new RuntimeException("ALREADY PROCESSING !!!");
|
||||
} else if (this.canBeginProcessing()) {
|
||||
this.isProcessing = true;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void processRecordedQueue() {
|
||||
if (!this.isProcessing) {
|
||||
throw new RuntimeException("NOT PROCESSING !!!");
|
||||
}
|
||||
}
|
||||
|
||||
public void endProcessing() {
|
||||
if (this.isProcessing) {
|
||||
this.isProcessing = false;
|
||||
this.renderingBuffer = this.processedBuffer;
|
||||
this.processedBuffer = this.recordingBuffer;
|
||||
} else {
|
||||
throw new RuntimeException("NOT PROCESSING !!!");
|
||||
}
|
||||
}
|
||||
|
||||
public ConcurrentLinkedQueue<RenderCall> startRendering() {
|
||||
return this.renderCalls.get(this.renderingBuffer);
|
||||
}
|
||||
|
||||
public ConcurrentLinkedQueue<RenderCall> getRecordingQueue() {
|
||||
return this.renderCalls.get(this.recordingBuffer);
|
||||
}
|
||||
|
||||
public ConcurrentLinkedQueue<RenderCall> getProcessedQueue() {
|
||||
return this.renderCalls.get(this.processedBuffer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
package com.mojang.blaze3d.pipeline;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.platform.TextureUtil;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||
import com.mojang.blaze3d.vertex.BufferUploader;
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import com.mojang.blaze3d.vertex.Tesselator;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.mojang.blaze3d.vertex.VertexSorting;
|
||||
import java.nio.IntBuffer;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.ShaderInstance;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.joml.Matrix4f;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public abstract class RenderTarget {
|
||||
private static final int RED_CHANNEL = 0;
|
||||
private static final int GREEN_CHANNEL = 1;
|
||||
private static final int BLUE_CHANNEL = 2;
|
||||
private static final int ALPHA_CHANNEL = 3;
|
||||
public int width;
|
||||
public int height;
|
||||
public int viewWidth;
|
||||
public int viewHeight;
|
||||
public final boolean useDepth;
|
||||
public int frameBufferId;
|
||||
protected int colorTextureId;
|
||||
protected int depthBufferId;
|
||||
private final float[] clearChannels = Util.make(() -> {
|
||||
return new float[]{1.0F, 1.0F, 1.0F, 0.0F};
|
||||
});
|
||||
public int filterMode;
|
||||
|
||||
public RenderTarget(boolean p_166199_) {
|
||||
this.useDepth = p_166199_;
|
||||
this.frameBufferId = -1;
|
||||
this.colorTextureId = -1;
|
||||
this.depthBufferId = -1;
|
||||
}
|
||||
|
||||
public void resize(int p_83942_, int p_83943_, boolean p_83944_) {
|
||||
if (!RenderSystem.isOnRenderThread()) {
|
||||
RenderSystem.recordRenderCall(() -> {
|
||||
this._resize(p_83942_, p_83943_, p_83944_);
|
||||
});
|
||||
} else {
|
||||
this._resize(p_83942_, p_83943_, p_83944_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void _resize(int p_83965_, int p_83966_, boolean p_83967_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GlStateManager._enableDepthTest();
|
||||
if (this.frameBufferId >= 0) {
|
||||
this.destroyBuffers();
|
||||
}
|
||||
|
||||
this.createBuffers(p_83965_, p_83966_, p_83967_);
|
||||
GlStateManager._glBindFramebuffer(36160, 0);
|
||||
}
|
||||
|
||||
public void destroyBuffers() {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
this.unbindRead();
|
||||
this.unbindWrite();
|
||||
if (this.depthBufferId > -1) {
|
||||
TextureUtil.releaseTextureId(this.depthBufferId);
|
||||
this.depthBufferId = -1;
|
||||
}
|
||||
|
||||
if (this.colorTextureId > -1) {
|
||||
TextureUtil.releaseTextureId(this.colorTextureId);
|
||||
this.colorTextureId = -1;
|
||||
}
|
||||
|
||||
if (this.frameBufferId > -1) {
|
||||
GlStateManager._glBindFramebuffer(36160, 0);
|
||||
GlStateManager._glDeleteFramebuffers(this.frameBufferId);
|
||||
this.frameBufferId = -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void copyDepthFrom(RenderTarget p_83946_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GlStateManager._glBindFramebuffer(36008, p_83946_.frameBufferId);
|
||||
GlStateManager._glBindFramebuffer(36009, this.frameBufferId);
|
||||
GlStateManager._glBlitFrameBuffer(0, 0, p_83946_.width, p_83946_.height, 0, 0, this.width, this.height, 256, 9728);
|
||||
GlStateManager._glBindFramebuffer(36160, 0);
|
||||
}
|
||||
|
||||
public void createBuffers(int p_83951_, int p_83952_, boolean p_83953_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
int i = RenderSystem.maxSupportedTextureSize();
|
||||
if (p_83951_ > 0 && p_83951_ <= i && p_83952_ > 0 && p_83952_ <= i) {
|
||||
this.viewWidth = p_83951_;
|
||||
this.viewHeight = p_83952_;
|
||||
this.width = p_83951_;
|
||||
this.height = p_83952_;
|
||||
this.frameBufferId = GlStateManager.glGenFramebuffers();
|
||||
this.colorTextureId = TextureUtil.generateTextureId();
|
||||
if (this.useDepth) {
|
||||
this.depthBufferId = TextureUtil.generateTextureId();
|
||||
GlStateManager._bindTexture(this.depthBufferId);
|
||||
GlStateManager._texParameter(3553, 10241, 9728);
|
||||
GlStateManager._texParameter(3553, 10240, 9728);
|
||||
GlStateManager._texParameter(3553, 34892, 0);
|
||||
GlStateManager._texParameter(3553, 10242, 33071);
|
||||
GlStateManager._texParameter(3553, 10243, 33071);
|
||||
if (!stencilEnabled)
|
||||
GlStateManager._texImage2D(3553, 0, 6402, this.width, this.height, 0, 6402, 5126, (IntBuffer)null);
|
||||
else
|
||||
GlStateManager._texImage2D(3553, 0, org.lwjgl.opengl.GL30.GL_DEPTH32F_STENCIL8, this.width, this.height, 0, org.lwjgl.opengl.GL30.GL_DEPTH_STENCIL, org.lwjgl.opengl.GL30.GL_FLOAT_32_UNSIGNED_INT_24_8_REV, null);
|
||||
}
|
||||
|
||||
this.setFilterMode(9728);
|
||||
GlStateManager._bindTexture(this.colorTextureId);
|
||||
GlStateManager._texParameter(3553, 10242, 33071);
|
||||
GlStateManager._texParameter(3553, 10243, 33071);
|
||||
GlStateManager._texImage2D(3553, 0, 32856, this.width, this.height, 0, 6408, 5121, (IntBuffer)null);
|
||||
GlStateManager._glBindFramebuffer(36160, this.frameBufferId);
|
||||
GlStateManager._glFramebufferTexture2D(36160, 36064, 3553, this.colorTextureId, 0);
|
||||
if (this.useDepth) {
|
||||
if(!stencilEnabled)
|
||||
GlStateManager._glFramebufferTexture2D(36160, 36096, 3553, this.depthBufferId, 0);
|
||||
else if(net.minecraftforge.common.ForgeConfig.CLIENT.useCombinedDepthStencilAttachment.get()) {
|
||||
GlStateManager._glFramebufferTexture2D(org.lwjgl.opengl.GL30.GL_FRAMEBUFFER, org.lwjgl.opengl.GL30.GL_DEPTH_STENCIL_ATTACHMENT, 3553, this.depthBufferId, 0);
|
||||
} else {
|
||||
GlStateManager._glFramebufferTexture2D(org.lwjgl.opengl.GL30.GL_FRAMEBUFFER, org.lwjgl.opengl.GL30.GL_DEPTH_ATTACHMENT, 3553, this.depthBufferId, 0);
|
||||
GlStateManager._glFramebufferTexture2D(org.lwjgl.opengl.GL30.GL_FRAMEBUFFER, org.lwjgl.opengl.GL30.GL_STENCIL_ATTACHMENT, 3553, this.depthBufferId, 0);
|
||||
}
|
||||
}
|
||||
|
||||
this.checkStatus();
|
||||
this.clear(p_83953_);
|
||||
this.unbindRead();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Window " + p_83951_ + "x" + p_83952_ + " size out of bounds (max. size: " + i + ")");
|
||||
}
|
||||
}
|
||||
|
||||
public void setFilterMode(int p_83937_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
this.filterMode = p_83937_;
|
||||
GlStateManager._bindTexture(this.colorTextureId);
|
||||
GlStateManager._texParameter(3553, 10241, p_83937_);
|
||||
GlStateManager._texParameter(3553, 10240, p_83937_);
|
||||
GlStateManager._bindTexture(0);
|
||||
}
|
||||
|
||||
public void checkStatus() {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
int i = GlStateManager.glCheckFramebufferStatus(36160);
|
||||
if (i != 36053) {
|
||||
if (i == 36054) {
|
||||
throw new RuntimeException("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
|
||||
} else if (i == 36055) {
|
||||
throw new RuntimeException("GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
|
||||
} else if (i == 36059) {
|
||||
throw new RuntimeException("GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER");
|
||||
} else if (i == 36060) {
|
||||
throw new RuntimeException("GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER");
|
||||
} else if (i == 36061) {
|
||||
throw new RuntimeException("GL_FRAMEBUFFER_UNSUPPORTED");
|
||||
} else if (i == 1285) {
|
||||
throw new RuntimeException("GL_OUT_OF_MEMORY");
|
||||
} else {
|
||||
throw new RuntimeException("glCheckFramebufferStatus returned unknown status:" + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void bindRead() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GlStateManager._bindTexture(this.colorTextureId);
|
||||
}
|
||||
|
||||
public void unbindRead() {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GlStateManager._bindTexture(0);
|
||||
}
|
||||
|
||||
public void bindWrite(boolean p_83948_) {
|
||||
if (!RenderSystem.isOnRenderThread()) {
|
||||
RenderSystem.recordRenderCall(() -> {
|
||||
this._bindWrite(p_83948_);
|
||||
});
|
||||
} else {
|
||||
this._bindWrite(p_83948_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void _bindWrite(boolean p_83962_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GlStateManager._glBindFramebuffer(36160, this.frameBufferId);
|
||||
if (p_83962_) {
|
||||
GlStateManager._viewport(0, 0, this.viewWidth, this.viewHeight);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void unbindWrite() {
|
||||
if (!RenderSystem.isOnRenderThread()) {
|
||||
RenderSystem.recordRenderCall(() -> {
|
||||
GlStateManager._glBindFramebuffer(36160, 0);
|
||||
});
|
||||
} else {
|
||||
GlStateManager._glBindFramebuffer(36160, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setClearColor(float p_83932_, float p_83933_, float p_83934_, float p_83935_) {
|
||||
this.clearChannels[0] = p_83932_;
|
||||
this.clearChannels[1] = p_83933_;
|
||||
this.clearChannels[2] = p_83934_;
|
||||
this.clearChannels[3] = p_83935_;
|
||||
}
|
||||
|
||||
public void blitToScreen(int p_83939_, int p_83940_) {
|
||||
this.blitToScreen(p_83939_, p_83940_, true);
|
||||
}
|
||||
|
||||
public void blitToScreen(int p_83958_, int p_83959_, boolean p_83960_) {
|
||||
RenderSystem.assertOnGameThreadOrInit();
|
||||
if (!RenderSystem.isInInitPhase()) {
|
||||
RenderSystem.recordRenderCall(() -> {
|
||||
this._blitToScreen(p_83958_, p_83959_, p_83960_);
|
||||
});
|
||||
} else {
|
||||
this._blitToScreen(p_83958_, p_83959_, p_83960_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void _blitToScreen(int p_83972_, int p_83973_, boolean p_83974_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GlStateManager._colorMask(true, true, true, false);
|
||||
GlStateManager._disableDepthTest();
|
||||
GlStateManager._depthMask(false);
|
||||
GlStateManager._viewport(0, 0, p_83972_, p_83973_);
|
||||
if (p_83974_) {
|
||||
GlStateManager._disableBlend();
|
||||
}
|
||||
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
ShaderInstance shaderinstance = minecraft.gameRenderer.blitShader;
|
||||
shaderinstance.setSampler("DiffuseSampler", this.colorTextureId);
|
||||
Matrix4f matrix4f = (new Matrix4f()).setOrtho(0.0F, (float)p_83972_, (float)p_83973_, 0.0F, 1000.0F, 3000.0F);
|
||||
RenderSystem.setProjectionMatrix(matrix4f, VertexSorting.ORTHOGRAPHIC_Z);
|
||||
if (shaderinstance.MODEL_VIEW_MATRIX != null) {
|
||||
shaderinstance.MODEL_VIEW_MATRIX.set((new Matrix4f()).translation(0.0F, 0.0F, -2000.0F));
|
||||
}
|
||||
|
||||
if (shaderinstance.PROJECTION_MATRIX != null) {
|
||||
shaderinstance.PROJECTION_MATRIX.set(matrix4f);
|
||||
}
|
||||
|
||||
shaderinstance.apply();
|
||||
float f = (float)p_83972_;
|
||||
float f1 = (float)p_83973_;
|
||||
float f2 = (float)this.viewWidth / (float)this.width;
|
||||
float f3 = (float)this.viewHeight / (float)this.height;
|
||||
Tesselator tesselator = RenderSystem.renderThreadTesselator();
|
||||
BufferBuilder bufferbuilder = tesselator.getBuilder();
|
||||
bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR);
|
||||
bufferbuilder.vertex(0.0D, (double)f1, 0.0D).uv(0.0F, 0.0F).color(255, 255, 255, 255).endVertex();
|
||||
bufferbuilder.vertex((double)f, (double)f1, 0.0D).uv(f2, 0.0F).color(255, 255, 255, 255).endVertex();
|
||||
bufferbuilder.vertex((double)f, 0.0D, 0.0D).uv(f2, f3).color(255, 255, 255, 255).endVertex();
|
||||
bufferbuilder.vertex(0.0D, 0.0D, 0.0D).uv(0.0F, f3).color(255, 255, 255, 255).endVertex();
|
||||
BufferUploader.draw(bufferbuilder.end());
|
||||
shaderinstance.clear();
|
||||
GlStateManager._depthMask(true);
|
||||
GlStateManager._colorMask(true, true, true, true);
|
||||
}
|
||||
|
||||
public void clear(boolean p_83955_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
this.bindWrite(true);
|
||||
GlStateManager._clearColor(this.clearChannels[0], this.clearChannels[1], this.clearChannels[2], this.clearChannels[3]);
|
||||
int i = 16384;
|
||||
if (this.useDepth) {
|
||||
GlStateManager._clearDepth(1.0D);
|
||||
i |= 256;
|
||||
}
|
||||
|
||||
GlStateManager._clear(i, p_83955_);
|
||||
this.unbindWrite();
|
||||
}
|
||||
|
||||
public int getColorTextureId() {
|
||||
return this.colorTextureId;
|
||||
}
|
||||
|
||||
public int getDepthTextureId() {
|
||||
return this.depthBufferId;
|
||||
}
|
||||
|
||||
/*================================ FORGE START ================================================*/
|
||||
private boolean stencilEnabled = false;
|
||||
/**
|
||||
* Attempts to enable 8 bits of stencil buffer on this FrameBuffer.
|
||||
* Modders must call this directly to set things up.
|
||||
* This is to prevent the default cause where graphics cards do not support stencil bits.
|
||||
* <b>Make sure to call this on the main render thread!</b>
|
||||
*/
|
||||
public void enableStencil() {
|
||||
if(stencilEnabled) return;
|
||||
stencilEnabled = true;
|
||||
this.resize(viewWidth, viewHeight, net.minecraft.client.Minecraft.ON_OSX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns wither or not this FBO has been successfully initialized with stencil bits.
|
||||
* If not, and a modder wishes it to be, they must call enableStencil.
|
||||
*/
|
||||
public boolean isStencilEnabled() {
|
||||
return this.stencilEnabled;
|
||||
}
|
||||
/*================================ FORGE END ================================================*/
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.mojang.blaze3d.pipeline;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class TextureTarget extends RenderTarget {
|
||||
public TextureTarget(int p_166213_, int p_166214_, boolean p_166215_, boolean p_166216_) {
|
||||
super(p_166215_);
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
this.resize(p_166213_, p_166214_, p_166216_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
package com.mojang.blaze3d.pipeline;
|
||||
|
||||
import com.mojang.blaze3d.FieldsAreNonnullByDefault;
|
||||
import com.mojang.blaze3d.MethodsReturnNonnullByDefault;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.mojang.blaze3d.platform;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import java.nio.ByteBuffer;
|
||||
import net.minecraft.util.StringDecomposer;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.glfw.GLFWErrorCallback;
|
||||
import org.lwjgl.glfw.GLFWErrorCallbackI;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class ClipboardManager {
|
||||
public static final int FORMAT_UNAVAILABLE = 65545;
|
||||
private final ByteBuffer clipboardScratchBuffer = BufferUtils.createByteBuffer(8192);
|
||||
|
||||
public String getClipboard(long p_83996_, GLFWErrorCallbackI p_83997_) {
|
||||
GLFWErrorCallback glfwerrorcallback = GLFW.glfwSetErrorCallback(p_83997_);
|
||||
String s = GLFW.glfwGetClipboardString(p_83996_);
|
||||
s = s != null ? StringDecomposer.filterBrokenSurrogates(s) : "";
|
||||
GLFWErrorCallback glfwerrorcallback1 = GLFW.glfwSetErrorCallback(glfwerrorcallback);
|
||||
if (glfwerrorcallback1 != null) {
|
||||
glfwerrorcallback1.free();
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
private static void pushClipboard(long p_83992_, ByteBuffer p_83993_, byte[] p_83994_) {
|
||||
p_83993_.clear();
|
||||
p_83993_.put(p_83994_);
|
||||
p_83993_.put((byte)0);
|
||||
p_83993_.flip();
|
||||
GLFW.glfwSetClipboardString(p_83992_, p_83993_);
|
||||
}
|
||||
|
||||
public void setClipboard(long p_83989_, String p_83990_) {
|
||||
byte[] abyte = p_83990_.getBytes(Charsets.UTF_8);
|
||||
int i = abyte.length + 1;
|
||||
if (i < this.clipboardScratchBuffer.capacity()) {
|
||||
pushClipboard(p_83989_, this.clipboardScratchBuffer, abyte);
|
||||
} else {
|
||||
ByteBuffer bytebuffer = MemoryUtil.memAlloc(i);
|
||||
|
||||
try {
|
||||
pushClipboard(p_83989_, bytebuffer, abyte);
|
||||
} finally {
|
||||
MemoryUtil.memFree(bytebuffer);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.mojang.blaze3d.platform;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.system.Pointer;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class DebugMemoryUntracker {
|
||||
@Nullable
|
||||
private static final MethodHandle UNTRACK = GLX.make(() -> {
|
||||
try {
|
||||
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||
Class<?> oclass = Class.forName("org.lwjgl.system.MemoryManage$DebugAllocator");
|
||||
Method method = oclass.getDeclaredMethod("untrack", Long.TYPE);
|
||||
method.setAccessible(true);
|
||||
Field field = Class.forName("org.lwjgl.system.MemoryUtil$LazyInit").getDeclaredField("ALLOCATOR");
|
||||
field.setAccessible(true);
|
||||
Object object = field.get((Object)null);
|
||||
return oclass.isInstance(object) ? lookup.unreflect(method) : null;
|
||||
} catch (NoSuchMethodException | NoSuchFieldException | IllegalAccessException | ClassNotFoundException classnotfoundexception) {
|
||||
throw new RuntimeException(classnotfoundexception);
|
||||
}
|
||||
});
|
||||
|
||||
public static void untrack(long p_84002_) {
|
||||
if (UNTRACK != null) {
|
||||
try {
|
||||
UNTRACK.invoke(p_84002_);
|
||||
} catch (Throwable throwable) {
|
||||
throw new RuntimeException(throwable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void untrack(Pointer p_84004_) {
|
||||
untrack(p_84004_.address());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.mojang.blaze3d.platform;
|
||||
|
||||
import java.util.OptionalInt;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class DisplayData {
|
||||
public final int width;
|
||||
public final int height;
|
||||
public final OptionalInt fullscreenWidth;
|
||||
public final OptionalInt fullscreenHeight;
|
||||
public final boolean isFullscreen;
|
||||
|
||||
public DisplayData(int p_84011_, int p_84012_, OptionalInt p_84013_, OptionalInt p_84014_, boolean p_84015_) {
|
||||
this.width = p_84011_;
|
||||
this.height = p_84012_;
|
||||
this.fullscreenWidth = p_84013_;
|
||||
this.fullscreenHeight = p_84014_;
|
||||
this.isFullscreen = p_84015_;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
package com.mojang.blaze3d.platform;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.blaze3d.DontObfuscate;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import com.mojang.blaze3d.vertex.Tesselator;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.LongSupplier;
|
||||
import java.util.function.Supplier;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.Version;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.glfw.GLFWErrorCallback;
|
||||
import org.lwjgl.glfw.GLFWErrorCallbackI;
|
||||
import org.lwjgl.glfw.GLFWVidMode;
|
||||
import org.slf4j.Logger;
|
||||
import oshi.SystemInfo;
|
||||
import oshi.hardware.CentralProcessor;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@DontObfuscate
|
||||
public class GLX {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static String cpuInfo;
|
||||
|
||||
public static String getOpenGLVersionString() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
return GLFW.glfwGetCurrentContext() == 0L ? "NO CONTEXT" : GlStateManager._getString(7937) + " GL version " + GlStateManager._getString(7938) + ", " + GlStateManager._getString(7936);
|
||||
}
|
||||
|
||||
public static int _getRefreshRate(Window p_69342_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
long i = GLFW.glfwGetWindowMonitor(p_69342_.getWindow());
|
||||
if (i == 0L) {
|
||||
i = GLFW.glfwGetPrimaryMonitor();
|
||||
}
|
||||
|
||||
GLFWVidMode glfwvidmode = i == 0L ? null : GLFW.glfwGetVideoMode(i);
|
||||
return glfwvidmode == null ? 0 : glfwvidmode.refreshRate();
|
||||
}
|
||||
|
||||
public static String _getLWJGLVersion() {
|
||||
RenderSystem.assertInInitPhase();
|
||||
return Version.getVersion();
|
||||
}
|
||||
|
||||
public static LongSupplier _initGlfw() {
|
||||
RenderSystem.assertInInitPhase();
|
||||
Window.checkGlfwError((p_242032_, p_242033_) -> {
|
||||
throw new IllegalStateException(String.format(Locale.ROOT, "GLFW error before init: [0x%X]%s", p_242032_, p_242033_));
|
||||
});
|
||||
List<String> list = Lists.newArrayList();
|
||||
GLFWErrorCallback glfwerrorcallback = GLFW.glfwSetErrorCallback((p_69365_, p_69366_) -> {
|
||||
list.add(String.format(Locale.ROOT, "GLFW error during init: [0x%X]%s", p_69365_, p_69366_));
|
||||
});
|
||||
if (!GLFW.glfwInit()) {
|
||||
throw new IllegalStateException("Failed to initialize GLFW, errors: " + Joiner.on(",").join(list));
|
||||
} else {
|
||||
LongSupplier longsupplier = () -> {
|
||||
return (long)(GLFW.glfwGetTime() * 1.0E9D);
|
||||
};
|
||||
|
||||
for(String s : list) {
|
||||
LOGGER.error("GLFW error collected during initialization: {}", (Object)s);
|
||||
}
|
||||
|
||||
RenderSystem.setErrorCallback(glfwerrorcallback);
|
||||
return longsupplier;
|
||||
}
|
||||
}
|
||||
|
||||
public static void _setGlfwErrorCallback(GLFWErrorCallbackI p_69353_) {
|
||||
RenderSystem.assertInInitPhase();
|
||||
GLFWErrorCallback glfwerrorcallback = GLFW.glfwSetErrorCallback(p_69353_);
|
||||
if (glfwerrorcallback != null) {
|
||||
glfwerrorcallback.free();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static boolean _shouldClose(Window p_69356_) {
|
||||
return GLFW.glfwWindowShouldClose(p_69356_.getWindow());
|
||||
}
|
||||
|
||||
public static void _init(int p_69344_, boolean p_69345_) {
|
||||
RenderSystem.assertInInitPhase();
|
||||
|
||||
try {
|
||||
CentralProcessor centralprocessor = (new SystemInfo()).getHardware().getProcessor();
|
||||
cpuInfo = String.format(Locale.ROOT, "%dx %s", centralprocessor.getLogicalProcessorCount(), centralprocessor.getProcessorIdentifier().getName()).replaceAll("\\s+", " ");
|
||||
} catch (Throwable throwable) {
|
||||
}
|
||||
|
||||
GlDebug.enableDebugCallback(p_69344_, p_69345_);
|
||||
}
|
||||
|
||||
public static String _getCpuInfo() {
|
||||
return cpuInfo == null ? "<unknown>" : cpuInfo;
|
||||
}
|
||||
|
||||
public static void _renderCrosshair(int p_69348_, boolean p_69349_, boolean p_69350_, boolean p_69351_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GlStateManager._depthMask(false);
|
||||
GlStateManager._disableCull();
|
||||
RenderSystem.setShader(GameRenderer::getRendertypeLinesShader);
|
||||
Tesselator tesselator = RenderSystem.renderThreadTesselator();
|
||||
BufferBuilder bufferbuilder = tesselator.getBuilder();
|
||||
RenderSystem.lineWidth(4.0F);
|
||||
bufferbuilder.begin(VertexFormat.Mode.LINES, DefaultVertexFormat.POSITION_COLOR_NORMAL);
|
||||
if (p_69349_) {
|
||||
bufferbuilder.vertex(0.0D, 0.0D, 0.0D).color(0, 0, 0, 255).normal(1.0F, 0.0F, 0.0F).endVertex();
|
||||
bufferbuilder.vertex((double)p_69348_, 0.0D, 0.0D).color(0, 0, 0, 255).normal(1.0F, 0.0F, 0.0F).endVertex();
|
||||
}
|
||||
|
||||
if (p_69350_) {
|
||||
bufferbuilder.vertex(0.0D, 0.0D, 0.0D).color(0, 0, 0, 255).normal(0.0F, 1.0F, 0.0F).endVertex();
|
||||
bufferbuilder.vertex(0.0D, (double)p_69348_, 0.0D).color(0, 0, 0, 255).normal(0.0F, 1.0F, 0.0F).endVertex();
|
||||
}
|
||||
|
||||
if (p_69351_) {
|
||||
bufferbuilder.vertex(0.0D, 0.0D, 0.0D).color(0, 0, 0, 255).normal(0.0F, 0.0F, 1.0F).endVertex();
|
||||
bufferbuilder.vertex(0.0D, 0.0D, (double)p_69348_).color(0, 0, 0, 255).normal(0.0F, 0.0F, 1.0F).endVertex();
|
||||
}
|
||||
|
||||
tesselator.end();
|
||||
RenderSystem.lineWidth(2.0F);
|
||||
bufferbuilder.begin(VertexFormat.Mode.LINES, DefaultVertexFormat.POSITION_COLOR_NORMAL);
|
||||
if (p_69349_) {
|
||||
bufferbuilder.vertex(0.0D, 0.0D, 0.0D).color(255, 0, 0, 255).normal(1.0F, 0.0F, 0.0F).endVertex();
|
||||
bufferbuilder.vertex((double)p_69348_, 0.0D, 0.0D).color(255, 0, 0, 255).normal(1.0F, 0.0F, 0.0F).endVertex();
|
||||
}
|
||||
|
||||
if (p_69350_) {
|
||||
bufferbuilder.vertex(0.0D, 0.0D, 0.0D).color(0, 255, 0, 255).normal(0.0F, 1.0F, 0.0F).endVertex();
|
||||
bufferbuilder.vertex(0.0D, (double)p_69348_, 0.0D).color(0, 255, 0, 255).normal(0.0F, 1.0F, 0.0F).endVertex();
|
||||
}
|
||||
|
||||
if (p_69351_) {
|
||||
bufferbuilder.vertex(0.0D, 0.0D, 0.0D).color(127, 127, 255, 255).normal(0.0F, 0.0F, 1.0F).endVertex();
|
||||
bufferbuilder.vertex(0.0D, 0.0D, (double)p_69348_).color(127, 127, 255, 255).normal(0.0F, 0.0F, 1.0F).endVertex();
|
||||
}
|
||||
|
||||
tesselator.end();
|
||||
RenderSystem.lineWidth(1.0F);
|
||||
GlStateManager._enableCull();
|
||||
GlStateManager._depthMask(true);
|
||||
}
|
||||
|
||||
public static <T> T make(Supplier<T> p_69374_) {
|
||||
return p_69374_.get();
|
||||
}
|
||||
|
||||
public static <T> T make(T p_69371_, Consumer<T> p_69372_) {
|
||||
p_69372_.accept(p_69371_);
|
||||
return p_69371_;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package com.mojang.blaze3d.platform;
|
||||
|
||||
import com.mojang.blaze3d.DontObfuscate;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@DontObfuscate
|
||||
public class GlConst {
|
||||
public static final int GL_READ_FRAMEBUFFER = 36008;
|
||||
public static final int GL_DRAW_FRAMEBUFFER = 36009;
|
||||
public static final int GL_TRUE = 1;
|
||||
public static final int GL_FALSE = 0;
|
||||
public static final int GL_NONE = 0;
|
||||
public static final int GL_LINES = 1;
|
||||
public static final int GL_LINE_STRIP = 3;
|
||||
public static final int GL_TRIANGLE_STRIP = 5;
|
||||
public static final int GL_TRIANGLE_FAN = 6;
|
||||
public static final int GL_TRIANGLES = 4;
|
||||
public static final int GL_WRITE_ONLY = 35001;
|
||||
public static final int GL_EQUAL = 514;
|
||||
public static final int GL_LEQUAL = 515;
|
||||
public static final int GL_GREATER = 516;
|
||||
public static final int GL_GEQUAL = 518;
|
||||
public static final int GL_ALWAYS = 519;
|
||||
public static final int GL_TEXTURE_MAG_FILTER = 10240;
|
||||
public static final int GL_TEXTURE_MIN_FILTER = 10241;
|
||||
public static final int GL_TEXTURE_WRAP_S = 10242;
|
||||
public static final int GL_TEXTURE_WRAP_T = 10243;
|
||||
public static final int GL_NEAREST = 9728;
|
||||
public static final int GL_LINEAR = 9729;
|
||||
public static final int GL_NEAREST_MIPMAP_LINEAR = 9986;
|
||||
public static final int GL_LINEAR_MIPMAP_LINEAR = 9987;
|
||||
public static final int GL_CLAMP_TO_EDGE = 33071;
|
||||
public static final int GL_FRONT = 1028;
|
||||
public static final int GL_FRONT_AND_BACK = 1032;
|
||||
public static final int GL_LINE = 6913;
|
||||
public static final int GL_FILL = 6914;
|
||||
public static final int GL_BYTE = 5120;
|
||||
public static final int GL_UNSIGNED_BYTE = 5121;
|
||||
public static final int GL_SHORT = 5122;
|
||||
public static final int GL_UNSIGNED_SHORT = 5123;
|
||||
public static final int GL_INT = 5124;
|
||||
public static final int GL_UNSIGNED_INT = 5125;
|
||||
public static final int GL_FLOAT = 5126;
|
||||
public static final int GL_ZERO = 0;
|
||||
public static final int GL_ONE = 1;
|
||||
public static final int GL_SRC_COLOR = 768;
|
||||
public static final int GL_ONE_MINUS_SRC_COLOR = 769;
|
||||
public static final int GL_SRC_ALPHA = 770;
|
||||
public static final int GL_ONE_MINUS_SRC_ALPHA = 771;
|
||||
public static final int GL_DST_ALPHA = 772;
|
||||
public static final int GL_ONE_MINUS_DST_ALPHA = 773;
|
||||
public static final int GL_DST_COLOR = 774;
|
||||
public static final int GL_ONE_MINUS_DST_COLOR = 775;
|
||||
public static final int GL_REPLACE = 7681;
|
||||
public static final int GL_DEPTH_BUFFER_BIT = 256;
|
||||
public static final int GL_COLOR_BUFFER_BIT = 16384;
|
||||
public static final int GL_RGBA8 = 32856;
|
||||
public static final int GL_PROXY_TEXTURE_2D = 32868;
|
||||
public static final int GL_RGBA = 6408;
|
||||
public static final int GL_TEXTURE_WIDTH = 4096;
|
||||
public static final int GL_BGR = 32992;
|
||||
public static final int GL_FUNC_ADD = 32774;
|
||||
public static final int GL_MIN = 32775;
|
||||
public static final int GL_MAX = 32776;
|
||||
public static final int GL_FUNC_SUBTRACT = 32778;
|
||||
public static final int GL_FUNC_REVERSE_SUBTRACT = 32779;
|
||||
public static final int GL_DEPTH_COMPONENT24 = 33190;
|
||||
public static final int GL_STATIC_DRAW = 35044;
|
||||
public static final int GL_DYNAMIC_DRAW = 35048;
|
||||
public static final int GL_UNPACK_SWAP_BYTES = 3312;
|
||||
public static final int GL_UNPACK_LSB_FIRST = 3313;
|
||||
public static final int GL_UNPACK_ROW_LENGTH = 3314;
|
||||
public static final int GL_UNPACK_SKIP_ROWS = 3315;
|
||||
public static final int GL_UNPACK_SKIP_PIXELS = 3316;
|
||||
public static final int GL_UNPACK_ALIGNMENT = 3317;
|
||||
public static final int GL_PACK_ALIGNMENT = 3333;
|
||||
public static final int GL_MAX_TEXTURE_SIZE = 3379;
|
||||
public static final int GL_TEXTURE_2D = 3553;
|
||||
public static final int GL_DEPTH_COMPONENT = 6402;
|
||||
public static final int GL_DEPTH_COMPONENT32 = 33191;
|
||||
public static final int GL_FRAMEBUFFER = 36160;
|
||||
public static final int GL_RENDERBUFFER = 36161;
|
||||
public static final int GL_COLOR_ATTACHMENT0 = 36064;
|
||||
public static final int GL_DEPTH_ATTACHMENT = 36096;
|
||||
public static final int GL_FRAMEBUFFER_COMPLETE = 36053;
|
||||
public static final int GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 36054;
|
||||
public static final int GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 36055;
|
||||
public static final int GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER = 36059;
|
||||
public static final int GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER = 36060;
|
||||
public static final int GL_FRAMEBUFFER_UNSUPPORTED = 36061;
|
||||
public static final int GL_LINK_STATUS = 35714;
|
||||
public static final int GL_COMPILE_STATUS = 35713;
|
||||
public static final int GL_VERTEX_SHADER = 35633;
|
||||
public static final int GL_FRAGMENT_SHADER = 35632;
|
||||
public static final int GL_TEXTURE0 = 33984;
|
||||
public static final int GL_TEXTURE1 = 33985;
|
||||
public static final int GL_TEXTURE2 = 33986;
|
||||
public static final int GL_DEPTH_TEXTURE_MODE = 34891;
|
||||
public static final int GL_TEXTURE_COMPARE_MODE = 34892;
|
||||
public static final int GL_ARRAY_BUFFER = 34962;
|
||||
public static final int GL_ELEMENT_ARRAY_BUFFER = 34963;
|
||||
public static final int GL_ALPHA_BIAS = 3357;
|
||||
public static final int GL_RGB = 6407;
|
||||
public static final int GL_RG = 33319;
|
||||
public static final int GL_RED = 6403;
|
||||
public static final int GL_OUT_OF_MEMORY = 1285;
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
package com.mojang.blaze3d.platform;
|
||||
|
||||
import com.google.common.collect.EvictingQueue;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.opengl.ARBDebugOutput;
|
||||
import org.lwjgl.opengl.GL;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GLCapabilities;
|
||||
import org.lwjgl.opengl.GLDebugMessageARBCallback;
|
||||
import org.lwjgl.opengl.GLDebugMessageCallback;
|
||||
import org.lwjgl.opengl.KHRDebug;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class GlDebug {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final int CIRCULAR_LOG_SIZE = 10;
|
||||
private static final Queue<GlDebug.LogEntry> MESSAGE_BUFFER = EvictingQueue.create(10);
|
||||
@Nullable
|
||||
private static volatile GlDebug.LogEntry lastEntry;
|
||||
private static final List<Integer> DEBUG_LEVELS = ImmutableList.of(37190, 37191, 37192, 33387);
|
||||
private static final List<Integer> DEBUG_LEVELS_ARB = ImmutableList.of(37190, 37191, 37192);
|
||||
private static boolean debugEnabled;
|
||||
|
||||
private static String printUnknownToken(int p_84037_) {
|
||||
return "Unknown (0x" + Integer.toHexString(p_84037_).toUpperCase() + ")";
|
||||
}
|
||||
|
||||
public static String sourceToString(int p_84056_) {
|
||||
switch (p_84056_) {
|
||||
case 33350:
|
||||
return "API";
|
||||
case 33351:
|
||||
return "WINDOW SYSTEM";
|
||||
case 33352:
|
||||
return "SHADER COMPILER";
|
||||
case 33353:
|
||||
return "THIRD PARTY";
|
||||
case 33354:
|
||||
return "APPLICATION";
|
||||
case 33355:
|
||||
return "OTHER";
|
||||
default:
|
||||
return printUnknownToken(p_84056_);
|
||||
}
|
||||
}
|
||||
|
||||
public static String typeToString(int p_84058_) {
|
||||
switch (p_84058_) {
|
||||
case 33356:
|
||||
return "ERROR";
|
||||
case 33357:
|
||||
return "DEPRECATED BEHAVIOR";
|
||||
case 33358:
|
||||
return "UNDEFINED BEHAVIOR";
|
||||
case 33359:
|
||||
return "PORTABILITY";
|
||||
case 33360:
|
||||
return "PERFORMANCE";
|
||||
case 33361:
|
||||
return "OTHER";
|
||||
case 33384:
|
||||
return "MARKER";
|
||||
default:
|
||||
return printUnknownToken(p_84058_);
|
||||
}
|
||||
}
|
||||
|
||||
public static String severityToString(int p_84060_) {
|
||||
switch (p_84060_) {
|
||||
case 33387:
|
||||
return "NOTIFICATION";
|
||||
case 37190:
|
||||
return "HIGH";
|
||||
case 37191:
|
||||
return "MEDIUM";
|
||||
case 37192:
|
||||
return "LOW";
|
||||
default:
|
||||
return printUnknownToken(p_84060_);
|
||||
}
|
||||
}
|
||||
|
||||
private static void printDebugLog(int p_84039_, int p_84040_, int p_84041_, int p_84042_, int p_84043_, long p_84044_, long p_84045_) {
|
||||
String s = GLDebugMessageCallback.getMessage(p_84043_, p_84044_);
|
||||
GlDebug.LogEntry gldebug$logentry;
|
||||
synchronized(MESSAGE_BUFFER) {
|
||||
gldebug$logentry = lastEntry;
|
||||
if (gldebug$logentry != null && gldebug$logentry.isSame(p_84039_, p_84040_, p_84041_, p_84042_, s)) {
|
||||
++gldebug$logentry.count;
|
||||
} else {
|
||||
gldebug$logentry = new GlDebug.LogEntry(p_84039_, p_84040_, p_84041_, p_84042_, s);
|
||||
MESSAGE_BUFFER.add(gldebug$logentry);
|
||||
lastEntry = gldebug$logentry;
|
||||
}
|
||||
}
|
||||
|
||||
LOGGER.info("OpenGL debug message: {}", (Object)gldebug$logentry);
|
||||
}
|
||||
|
||||
public static List<String> getLastOpenGlDebugMessages() {
|
||||
synchronized(MESSAGE_BUFFER) {
|
||||
List<String> list = Lists.newArrayListWithCapacity(MESSAGE_BUFFER.size());
|
||||
|
||||
for(GlDebug.LogEntry gldebug$logentry : MESSAGE_BUFFER) {
|
||||
list.add(gldebug$logentry + " x " + gldebug$logentry.count);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isDebugEnabled() {
|
||||
return debugEnabled;
|
||||
}
|
||||
|
||||
public static void enableDebugCallback(int p_84050_, boolean p_84051_) {
|
||||
RenderSystem.assertInInitPhase();
|
||||
if (p_84050_ > 0) {
|
||||
GLCapabilities glcapabilities = GL.getCapabilities();
|
||||
if (glcapabilities.GL_KHR_debug) {
|
||||
debugEnabled = true;
|
||||
GL11.glEnable(37600);
|
||||
if (p_84051_) {
|
||||
GL11.glEnable(33346);
|
||||
}
|
||||
|
||||
for(int i = 0; i < DEBUG_LEVELS.size(); ++i) {
|
||||
boolean flag = i < p_84050_;
|
||||
KHRDebug.glDebugMessageControl(4352, 4352, DEBUG_LEVELS.get(i), (int[])null, flag);
|
||||
}
|
||||
|
||||
KHRDebug.glDebugMessageCallback(GLX.make(GLDebugMessageCallback.create(GlDebug::printDebugLog), DebugMemoryUntracker::untrack), 0L);
|
||||
} else if (glcapabilities.GL_ARB_debug_output) {
|
||||
debugEnabled = true;
|
||||
if (p_84051_) {
|
||||
GL11.glEnable(33346);
|
||||
}
|
||||
|
||||
for(int j = 0; j < DEBUG_LEVELS_ARB.size(); ++j) {
|
||||
boolean flag1 = j < p_84050_;
|
||||
ARBDebugOutput.glDebugMessageControlARB(4352, 4352, DEBUG_LEVELS_ARB.get(j), (int[])null, flag1);
|
||||
}
|
||||
|
||||
ARBDebugOutput.glDebugMessageCallbackARB(GLX.make(GLDebugMessageARBCallback.create(GlDebug::printDebugLog), DebugMemoryUntracker::untrack), 0L);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class LogEntry {
|
||||
private final int id;
|
||||
private final int source;
|
||||
private final int type;
|
||||
private final int severity;
|
||||
private final String message;
|
||||
int count = 1;
|
||||
|
||||
LogEntry(int p_166234_, int p_166235_, int p_166236_, int p_166237_, String p_166238_) {
|
||||
this.id = p_166236_;
|
||||
this.source = p_166234_;
|
||||
this.type = p_166235_;
|
||||
this.severity = p_166237_;
|
||||
this.message = p_166238_;
|
||||
}
|
||||
|
||||
boolean isSame(int p_166240_, int p_166241_, int p_166242_, int p_166243_, String p_166244_) {
|
||||
return p_166241_ == this.type && p_166240_ == this.source && p_166242_ == this.id && p_166243_ == this.severity && p_166244_.equals(this.message);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "id=" + this.id + ", source=" + GlDebug.sourceToString(this.source) + ", type=" + GlDebug.typeToString(this.type) + ", severity=" + GlDebug.severityToString(this.severity) + ", message='" + this.message + "'";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,954 @@
|
||||
package com.mojang.blaze3d.platform;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.mojang.blaze3d.DontObfuscate;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.IntStream;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4f;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL13;
|
||||
import org.lwjgl.opengl.GL14;
|
||||
import org.lwjgl.opengl.GL15;
|
||||
import org.lwjgl.opengl.GL20;
|
||||
import org.lwjgl.opengl.GL20C;
|
||||
import org.lwjgl.opengl.GL30;
|
||||
import org.lwjgl.opengl.GL32C;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@DontObfuscate
|
||||
public class GlStateManager {
|
||||
private static final boolean ON_LINUX = Util.getPlatform() == Util.OS.LINUX;
|
||||
public static final int TEXTURE_COUNT = 12;
|
||||
private static final GlStateManager.BlendState BLEND = new GlStateManager.BlendState();
|
||||
private static final GlStateManager.DepthState DEPTH = new GlStateManager.DepthState();
|
||||
private static final GlStateManager.CullState CULL = new GlStateManager.CullState();
|
||||
private static final GlStateManager.PolygonOffsetState POLY_OFFSET = new GlStateManager.PolygonOffsetState();
|
||||
private static final GlStateManager.ColorLogicState COLOR_LOGIC = new GlStateManager.ColorLogicState();
|
||||
private static final GlStateManager.StencilState STENCIL = new GlStateManager.StencilState();
|
||||
private static final GlStateManager.ScissorState SCISSOR = new GlStateManager.ScissorState();
|
||||
private static int activeTexture;
|
||||
private static final GlStateManager.TextureState[] TEXTURES = IntStream.range(0, 12).mapToObj((p_157120_) -> {
|
||||
return new GlStateManager.TextureState();
|
||||
}).toArray((p_157122_) -> {
|
||||
return new GlStateManager.TextureState[p_157122_];
|
||||
});
|
||||
private static final GlStateManager.ColorMask COLOR_MASK = new GlStateManager.ColorMask();
|
||||
|
||||
public static void _disableScissorTest() {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
SCISSOR.mode.disable();
|
||||
}
|
||||
|
||||
public static void _enableScissorTest() {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
SCISSOR.mode.enable();
|
||||
}
|
||||
|
||||
public static void _scissorBox(int p_84169_, int p_84170_, int p_84171_, int p_84172_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL20.glScissor(p_84169_, p_84170_, p_84171_, p_84172_);
|
||||
}
|
||||
|
||||
public static void _disableDepthTest() {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
DEPTH.mode.disable();
|
||||
}
|
||||
|
||||
public static void _enableDepthTest() {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
DEPTH.mode.enable();
|
||||
}
|
||||
|
||||
public static void _depthFunc(int p_84324_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
if (p_84324_ != DEPTH.func) {
|
||||
DEPTH.func = p_84324_;
|
||||
GL11.glDepthFunc(p_84324_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void _depthMask(boolean p_84299_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
if (p_84299_ != DEPTH.mask) {
|
||||
DEPTH.mask = p_84299_;
|
||||
GL11.glDepthMask(p_84299_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void _disableBlend() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
BLEND.mode.disable();
|
||||
}
|
||||
|
||||
public static void _enableBlend() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
BLEND.mode.enable();
|
||||
}
|
||||
|
||||
public static void _blendFunc(int p_84329_, int p_84330_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
if (p_84329_ != BLEND.srcRgb || p_84330_ != BLEND.dstRgb) {
|
||||
BLEND.srcRgb = p_84329_;
|
||||
BLEND.dstRgb = p_84330_;
|
||||
GL11.glBlendFunc(p_84329_, p_84330_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void _blendFuncSeparate(int p_84336_, int p_84337_, int p_84338_, int p_84339_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
if (p_84336_ != BLEND.srcRgb || p_84337_ != BLEND.dstRgb || p_84338_ != BLEND.srcAlpha || p_84339_ != BLEND.dstAlpha) {
|
||||
BLEND.srcRgb = p_84336_;
|
||||
BLEND.dstRgb = p_84337_;
|
||||
BLEND.srcAlpha = p_84338_;
|
||||
BLEND.dstAlpha = p_84339_;
|
||||
glBlendFuncSeparate(p_84336_, p_84337_, p_84338_, p_84339_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void _blendEquation(int p_84380_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL14.glBlendEquation(p_84380_);
|
||||
}
|
||||
|
||||
public static int glGetProgrami(int p_84382_, int p_84383_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
return GL20.glGetProgrami(p_84382_, p_84383_);
|
||||
}
|
||||
|
||||
public static void glAttachShader(int p_84424_, int p_84425_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL20.glAttachShader(p_84424_, p_84425_);
|
||||
}
|
||||
|
||||
public static void glDeleteShader(int p_84422_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL20.glDeleteShader(p_84422_);
|
||||
}
|
||||
|
||||
public static int glCreateShader(int p_84448_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
return GL20.glCreateShader(p_84448_);
|
||||
}
|
||||
|
||||
public static void glShaderSource(int p_157117_, List<String> p_157118_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
StringBuilder stringbuilder = new StringBuilder();
|
||||
|
||||
for(String s : p_157118_) {
|
||||
stringbuilder.append(s);
|
||||
}
|
||||
|
||||
byte[] abyte = stringbuilder.toString().getBytes(Charsets.UTF_8);
|
||||
ByteBuffer bytebuffer = MemoryUtil.memAlloc(abyte.length + 1);
|
||||
bytebuffer.put(abyte);
|
||||
bytebuffer.put((byte)0);
|
||||
bytebuffer.flip();
|
||||
|
||||
try (MemoryStack memorystack = MemoryStack.stackPush()) {
|
||||
PointerBuffer pointerbuffer = memorystack.mallocPointer(1);
|
||||
pointerbuffer.put(bytebuffer);
|
||||
GL20C.nglShaderSource(p_157117_, 1, pointerbuffer.address0(), 0L);
|
||||
} finally {
|
||||
MemoryUtil.memFree(bytebuffer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void glCompileShader(int p_84466_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL20.glCompileShader(p_84466_);
|
||||
}
|
||||
|
||||
public static int glGetShaderi(int p_84450_, int p_84451_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
return GL20.glGetShaderi(p_84450_, p_84451_);
|
||||
}
|
||||
|
||||
public static void _glUseProgram(int p_84479_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL20.glUseProgram(p_84479_);
|
||||
}
|
||||
|
||||
public static int glCreateProgram() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
return GL20.glCreateProgram();
|
||||
}
|
||||
|
||||
public static void glDeleteProgram(int p_84485_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL20.glDeleteProgram(p_84485_);
|
||||
}
|
||||
|
||||
public static void glLinkProgram(int p_84491_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL20.glLinkProgram(p_84491_);
|
||||
}
|
||||
|
||||
public static int _glGetUniformLocation(int p_84346_, CharSequence p_84347_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
return GL20.glGetUniformLocation(p_84346_, p_84347_);
|
||||
}
|
||||
|
||||
public static void _glUniform1(int p_84264_, IntBuffer p_84265_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL20.glUniform1iv(p_84264_, p_84265_);
|
||||
}
|
||||
|
||||
public static void _glUniform1i(int p_84468_, int p_84469_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL20.glUniform1i(p_84468_, p_84469_);
|
||||
}
|
||||
|
||||
public static void _glUniform1(int p_84349_, FloatBuffer p_84350_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL20.glUniform1fv(p_84349_, p_84350_);
|
||||
}
|
||||
|
||||
public static void _glUniform2(int p_84352_, IntBuffer p_84353_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL20.glUniform2iv(p_84352_, p_84353_);
|
||||
}
|
||||
|
||||
public static void _glUniform2(int p_84402_, FloatBuffer p_84403_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL20.glUniform2fv(p_84402_, p_84403_);
|
||||
}
|
||||
|
||||
public static void _glUniform3(int p_84405_, IntBuffer p_84406_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL20.glUniform3iv(p_84405_, p_84406_);
|
||||
}
|
||||
|
||||
public static void _glUniform3(int p_84436_, FloatBuffer p_84437_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL20.glUniform3fv(p_84436_, p_84437_);
|
||||
}
|
||||
|
||||
public static void _glUniform4(int p_84439_, IntBuffer p_84440_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL20.glUniform4iv(p_84439_, p_84440_);
|
||||
}
|
||||
|
||||
public static void _glUniform4(int p_84462_, FloatBuffer p_84463_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL20.glUniform4fv(p_84462_, p_84463_);
|
||||
}
|
||||
|
||||
public static void _glUniformMatrix2(int p_84270_, boolean p_84271_, FloatBuffer p_84272_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL20.glUniformMatrix2fv(p_84270_, p_84271_, p_84272_);
|
||||
}
|
||||
|
||||
public static void _glUniformMatrix3(int p_84355_, boolean p_84356_, FloatBuffer p_84357_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL20.glUniformMatrix3fv(p_84355_, p_84356_, p_84357_);
|
||||
}
|
||||
|
||||
public static void _glUniformMatrix4(int p_84408_, boolean p_84409_, FloatBuffer p_84410_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL20.glUniformMatrix4fv(p_84408_, p_84409_, p_84410_);
|
||||
}
|
||||
|
||||
public static int _glGetAttribLocation(int p_84399_, CharSequence p_84400_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
return GL20.glGetAttribLocation(p_84399_, p_84400_);
|
||||
}
|
||||
|
||||
public static void _glBindAttribLocation(int p_157062_, int p_157063_, CharSequence p_157064_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL20.glBindAttribLocation(p_157062_, p_157063_, p_157064_);
|
||||
}
|
||||
|
||||
public static int _glGenBuffers() {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
return GL15.glGenBuffers();
|
||||
}
|
||||
|
||||
public static int _glGenVertexArrays() {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
return GL30.glGenVertexArrays();
|
||||
}
|
||||
|
||||
public static void _glBindBuffer(int p_84481_, int p_84482_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL15.glBindBuffer(p_84481_, p_84482_);
|
||||
}
|
||||
|
||||
public static void _glBindVertexArray(int p_157069_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL30.glBindVertexArray(p_157069_);
|
||||
}
|
||||
|
||||
public static void _glBufferData(int p_84257_, ByteBuffer p_84258_, int p_84259_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL15.glBufferData(p_84257_, p_84258_, p_84259_);
|
||||
}
|
||||
|
||||
public static void _glBufferData(int p_157071_, long p_157072_, int p_157073_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL15.glBufferData(p_157071_, p_157072_, p_157073_);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ByteBuffer _glMapBuffer(int p_157091_, int p_157092_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
return GL15.glMapBuffer(p_157091_, p_157092_);
|
||||
}
|
||||
|
||||
public static void _glUnmapBuffer(int p_157099_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL15.glUnmapBuffer(p_157099_);
|
||||
}
|
||||
|
||||
public static void _glDeleteBuffers(int p_84497_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
if (ON_LINUX) {
|
||||
GL32C.glBindBuffer(34962, p_84497_);
|
||||
GL32C.glBufferData(34962, 0L, 35048);
|
||||
GL32C.glBindBuffer(34962, 0);
|
||||
}
|
||||
|
||||
GL15.glDeleteBuffers(p_84497_);
|
||||
}
|
||||
|
||||
public static void _glCopyTexSubImage2D(int p_84180_, int p_84181_, int p_84182_, int p_84183_, int p_84184_, int p_84185_, int p_84186_, int p_84187_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL20.glCopyTexSubImage2D(p_84180_, p_84181_, p_84182_, p_84183_, p_84184_, p_84185_, p_84186_, p_84187_);
|
||||
}
|
||||
|
||||
public static void _glDeleteVertexArrays(int p_157077_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL30.glDeleteVertexArrays(p_157077_);
|
||||
}
|
||||
|
||||
public static void _glBindFramebuffer(int p_84487_, int p_84488_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL30.glBindFramebuffer(p_84487_, p_84488_);
|
||||
}
|
||||
|
||||
public static void _glBlitFrameBuffer(int p_84189_, int p_84190_, int p_84191_, int p_84192_, int p_84193_, int p_84194_, int p_84195_, int p_84196_, int p_84197_, int p_84198_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL30.glBlitFramebuffer(p_84189_, p_84190_, p_84191_, p_84192_, p_84193_, p_84194_, p_84195_, p_84196_, p_84197_, p_84198_);
|
||||
}
|
||||
|
||||
public static void _glBindRenderbuffer(int p_157066_, int p_157067_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL30.glBindRenderbuffer(p_157066_, p_157067_);
|
||||
}
|
||||
|
||||
public static void _glDeleteRenderbuffers(int p_157075_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL30.glDeleteRenderbuffers(p_157075_);
|
||||
}
|
||||
|
||||
public static void _glDeleteFramebuffers(int p_84503_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL30.glDeleteFramebuffers(p_84503_);
|
||||
}
|
||||
|
||||
public static int glGenFramebuffers() {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
return GL30.glGenFramebuffers();
|
||||
}
|
||||
|
||||
public static int glGenRenderbuffers() {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
return GL30.glGenRenderbuffers();
|
||||
}
|
||||
|
||||
public static void _glRenderbufferStorage(int p_157094_, int p_157095_, int p_157096_, int p_157097_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL30.glRenderbufferStorage(p_157094_, p_157095_, p_157096_, p_157097_);
|
||||
}
|
||||
|
||||
public static void _glFramebufferRenderbuffer(int p_157085_, int p_157086_, int p_157087_, int p_157088_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL30.glFramebufferRenderbuffer(p_157085_, p_157086_, p_157087_, p_157088_);
|
||||
}
|
||||
|
||||
public static int glCheckFramebufferStatus(int p_84509_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
return GL30.glCheckFramebufferStatus(p_84509_);
|
||||
}
|
||||
|
||||
public static void _glFramebufferTexture2D(int p_84174_, int p_84175_, int p_84176_, int p_84177_, int p_84178_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL30.glFramebufferTexture2D(p_84174_, p_84175_, p_84176_, p_84177_, p_84178_);
|
||||
}
|
||||
|
||||
public static int getBoundFramebuffer() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
return _getInteger(36006);
|
||||
}
|
||||
|
||||
public static void glActiveTexture(int p_84515_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL13.glActiveTexture(p_84515_);
|
||||
}
|
||||
|
||||
public static void glBlendFuncSeparate(int p_84389_, int p_84390_, int p_84391_, int p_84392_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL14.glBlendFuncSeparate(p_84389_, p_84390_, p_84391_, p_84392_);
|
||||
}
|
||||
|
||||
public static String glGetShaderInfoLog(int p_84493_, int p_84494_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
return GL20.glGetShaderInfoLog(p_84493_, p_84494_);
|
||||
}
|
||||
|
||||
public static String glGetProgramInfoLog(int p_84499_, int p_84500_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
return GL20.glGetProgramInfoLog(p_84499_, p_84500_);
|
||||
}
|
||||
|
||||
public static void setupLevelDiffuseLighting(Vector3f p_254343_, Vector3f p_254532_, Matrix4f p_254339_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
Vector4f vector4f = p_254339_.transform(new Vector4f(p_254343_, 1.0F));
|
||||
Vector4f vector4f1 = p_254339_.transform(new Vector4f(p_254532_, 1.0F));
|
||||
RenderSystem.setShaderLights(new Vector3f(vector4f.x(), vector4f.y(), vector4f.z()), new Vector3f(vector4f1.x(), vector4f1.y(), vector4f1.z()));
|
||||
}
|
||||
|
||||
public static void setupGuiFlatDiffuseLighting(Vector3f p_254237_, Vector3f p_253658_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
Matrix4f matrix4f = (new Matrix4f()).scaling(1.0F, -1.0F, 1.0F).rotateY((-(float)Math.PI / 8F)).rotateX(2.3561945F);
|
||||
setupLevelDiffuseLighting(p_254237_, p_253658_, matrix4f);
|
||||
}
|
||||
|
||||
public static void setupGui3DDiffuseLighting(Vector3f p_254290_, Vector3f p_254528_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
Matrix4f matrix4f = (new Matrix4f()).rotationYXZ(1.0821041F, 3.2375858F, 0.0F).rotateYXZ((-(float)Math.PI / 8F), 2.3561945F, 0.0F);
|
||||
setupLevelDiffuseLighting(p_254290_, p_254528_, matrix4f);
|
||||
}
|
||||
|
||||
public static void _enableCull() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
CULL.enable.enable();
|
||||
}
|
||||
|
||||
public static void _disableCull() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
CULL.enable.disable();
|
||||
}
|
||||
|
||||
public static void _polygonMode(int p_84517_, int p_84518_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL11.glPolygonMode(p_84517_, p_84518_);
|
||||
}
|
||||
|
||||
public static void _enablePolygonOffset() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
POLY_OFFSET.fill.enable();
|
||||
}
|
||||
|
||||
public static void _disablePolygonOffset() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
POLY_OFFSET.fill.disable();
|
||||
}
|
||||
|
||||
public static void _polygonOffset(float p_84137_, float p_84138_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
if (p_84137_ != POLY_OFFSET.factor || p_84138_ != POLY_OFFSET.units) {
|
||||
POLY_OFFSET.factor = p_84137_;
|
||||
POLY_OFFSET.units = p_84138_;
|
||||
GL11.glPolygonOffset(p_84137_, p_84138_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void _enableColorLogicOp() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
COLOR_LOGIC.enable.enable();
|
||||
}
|
||||
|
||||
public static void _disableColorLogicOp() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
COLOR_LOGIC.enable.disable();
|
||||
}
|
||||
|
||||
public static void _logicOp(int p_84533_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
if (p_84533_ != COLOR_LOGIC.op) {
|
||||
COLOR_LOGIC.op = p_84533_;
|
||||
GL11.glLogicOp(p_84533_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void _activeTexture(int p_84539_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
if (activeTexture != p_84539_ - '\u84c0') {
|
||||
activeTexture = p_84539_ - '\u84c0';
|
||||
glActiveTexture(p_84539_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Stores the last values sent into glMultiTexCoord2f */
|
||||
public static float lastBrightnessX = 0.0f;
|
||||
public static float lastBrightnessY = 0.0f;
|
||||
public static void _texParameter(int p_84161_, int p_84162_, float p_84163_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL11.glTexParameterf(p_84161_, p_84162_, p_84163_);
|
||||
if (p_84161_ == GL13.GL_TEXTURE1) {
|
||||
lastBrightnessX = p_84162_;
|
||||
lastBrightnessY = p_84163_;
|
||||
}
|
||||
}
|
||||
|
||||
public static void _texParameter(int p_84332_, int p_84333_, int p_84334_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL11.glTexParameteri(p_84332_, p_84333_, p_84334_);
|
||||
}
|
||||
|
||||
public static int _getTexLevelParameter(int p_84385_, int p_84386_, int p_84387_) {
|
||||
RenderSystem.assertInInitPhase();
|
||||
return GL11.glGetTexLevelParameteri(p_84385_, p_84386_, p_84387_);
|
||||
}
|
||||
|
||||
public static int _genTexture() {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
return GL11.glGenTextures();
|
||||
}
|
||||
|
||||
public static void _genTextures(int[] p_84306_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL11.glGenTextures(p_84306_);
|
||||
}
|
||||
|
||||
public static void _deleteTexture(int p_84542_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL11.glDeleteTextures(p_84542_);
|
||||
|
||||
for(GlStateManager.TextureState glstatemanager$texturestate : TEXTURES) {
|
||||
if (glstatemanager$texturestate.binding == p_84542_) {
|
||||
glstatemanager$texturestate.binding = -1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void _deleteTextures(int[] p_84366_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
|
||||
for(GlStateManager.TextureState glstatemanager$texturestate : TEXTURES) {
|
||||
for(int i : p_84366_) {
|
||||
if (glstatemanager$texturestate.binding == i) {
|
||||
glstatemanager$texturestate.binding = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GL11.glDeleteTextures(p_84366_);
|
||||
}
|
||||
|
||||
public static void _bindTexture(int p_84545_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
if (p_84545_ != TEXTURES[activeTexture].binding) {
|
||||
TEXTURES[activeTexture].binding = p_84545_;
|
||||
GL11.glBindTexture(3553, p_84545_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static int _getActiveTexture() {
|
||||
return activeTexture + '\u84c0';
|
||||
}
|
||||
|
||||
public static void _texImage2D(int p_84210_, int p_84211_, int p_84212_, int p_84213_, int p_84214_, int p_84215_, int p_84216_, int p_84217_, @Nullable IntBuffer p_84218_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL11.glTexImage2D(p_84210_, p_84211_, p_84212_, p_84213_, p_84214_, p_84215_, p_84216_, p_84217_, p_84218_);
|
||||
}
|
||||
|
||||
public static void _texSubImage2D(int p_84200_, int p_84201_, int p_84202_, int p_84203_, int p_84204_, int p_84205_, int p_84206_, int p_84207_, long p_84208_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL11.glTexSubImage2D(p_84200_, p_84201_, p_84202_, p_84203_, p_84204_, p_84205_, p_84206_, p_84207_, p_84208_);
|
||||
}
|
||||
|
||||
public static void upload(int p_287776_, int p_287602_, int p_287633_, int p_287778_, int p_287752_, NativeImage.Format p_287608_, IntBuffer p_287753_, Consumer<IntBuffer> p_287739_) {
|
||||
if (!RenderSystem.isOnRenderThreadOrInit()) {
|
||||
RenderSystem.recordRenderCall(() -> {
|
||||
_upload(p_287776_, p_287602_, p_287633_, p_287778_, p_287752_, p_287608_, p_287753_, p_287739_);
|
||||
});
|
||||
} else {
|
||||
_upload(p_287776_, p_287602_, p_287633_, p_287778_, p_287752_, p_287608_, p_287753_, p_287739_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void _upload(int p_287672_, int p_287577_, int p_287618_, int p_287777_, int p_287707_, NativeImage.Format p_287692_, IntBuffer p_287674_, Consumer<IntBuffer> p_287588_) {
|
||||
try {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
_pixelStore(3314, p_287777_);
|
||||
_pixelStore(3316, 0);
|
||||
_pixelStore(3315, 0);
|
||||
p_287692_.setUnpackPixelStoreState();
|
||||
GL11.glTexSubImage2D(3553, p_287672_, p_287577_, p_287618_, p_287777_, p_287707_, p_287692_.glFormat(), 5121, p_287674_);
|
||||
} finally {
|
||||
p_287588_.accept(p_287674_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void _getTexImage(int p_84228_, int p_84229_, int p_84230_, int p_84231_, long p_84232_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL11.glGetTexImage(p_84228_, p_84229_, p_84230_, p_84231_, p_84232_);
|
||||
}
|
||||
|
||||
public static void _viewport(int p_84431_, int p_84432_, int p_84433_, int p_84434_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GlStateManager.Viewport.INSTANCE.x = p_84431_;
|
||||
GlStateManager.Viewport.INSTANCE.y = p_84432_;
|
||||
GlStateManager.Viewport.INSTANCE.width = p_84433_;
|
||||
GlStateManager.Viewport.INSTANCE.height = p_84434_;
|
||||
GL11.glViewport(p_84431_, p_84432_, p_84433_, p_84434_);
|
||||
}
|
||||
|
||||
public static void _colorMask(boolean p_84301_, boolean p_84302_, boolean p_84303_, boolean p_84304_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
if (p_84301_ != COLOR_MASK.red || p_84302_ != COLOR_MASK.green || p_84303_ != COLOR_MASK.blue || p_84304_ != COLOR_MASK.alpha) {
|
||||
COLOR_MASK.red = p_84301_;
|
||||
COLOR_MASK.green = p_84302_;
|
||||
COLOR_MASK.blue = p_84303_;
|
||||
COLOR_MASK.alpha = p_84304_;
|
||||
GL11.glColorMask(p_84301_, p_84302_, p_84303_, p_84304_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void _stencilFunc(int p_84427_, int p_84428_, int p_84429_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
if (p_84427_ != STENCIL.func.func || p_84427_ != STENCIL.func.ref || p_84427_ != STENCIL.func.mask) {
|
||||
STENCIL.func.func = p_84427_;
|
||||
STENCIL.func.ref = p_84428_;
|
||||
STENCIL.func.mask = p_84429_;
|
||||
GL11.glStencilFunc(p_84427_, p_84428_, p_84429_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void _stencilMask(int p_84551_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
if (p_84551_ != STENCIL.mask) {
|
||||
STENCIL.mask = p_84551_;
|
||||
GL11.glStencilMask(p_84551_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void _stencilOp(int p_84453_, int p_84454_, int p_84455_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
if (p_84453_ != STENCIL.fail || p_84454_ != STENCIL.zfail || p_84455_ != STENCIL.zpass) {
|
||||
STENCIL.fail = p_84453_;
|
||||
STENCIL.zfail = p_84454_;
|
||||
STENCIL.zpass = p_84455_;
|
||||
GL11.glStencilOp(p_84453_, p_84454_, p_84455_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void _clearDepth(double p_84122_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL11.glClearDepth(p_84122_);
|
||||
}
|
||||
|
||||
public static void _clearColor(float p_84319_, float p_84320_, float p_84321_, float p_84322_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL11.glClearColor(p_84319_, p_84320_, p_84321_, p_84322_);
|
||||
}
|
||||
|
||||
public static void _clearStencil(int p_84554_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL11.glClearStencil(p_84554_);
|
||||
}
|
||||
|
||||
public static void _clear(int p_84267_, boolean p_84268_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL11.glClear(p_84267_);
|
||||
if (p_84268_) {
|
||||
_getError();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void _glDrawPixels(int p_157079_, int p_157080_, int p_157081_, int p_157082_, long p_157083_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL11.glDrawPixels(p_157079_, p_157080_, p_157081_, p_157082_, p_157083_);
|
||||
}
|
||||
|
||||
public static void _vertexAttribPointer(int p_84239_, int p_84240_, int p_84241_, boolean p_84242_, int p_84243_, long p_84244_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL20.glVertexAttribPointer(p_84239_, p_84240_, p_84241_, p_84242_, p_84243_, p_84244_);
|
||||
}
|
||||
|
||||
public static void _vertexAttribIPointer(int p_157109_, int p_157110_, int p_157111_, int p_157112_, long p_157113_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL30.glVertexAttribIPointer(p_157109_, p_157110_, p_157111_, p_157112_, p_157113_);
|
||||
}
|
||||
|
||||
public static void _enableVertexAttribArray(int p_84566_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL20.glEnableVertexAttribArray(p_84566_);
|
||||
}
|
||||
|
||||
public static void _disableVertexAttribArray(int p_84087_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL20.glDisableVertexAttribArray(p_84087_);
|
||||
}
|
||||
|
||||
public static void _drawElements(int p_157054_, int p_157055_, int p_157056_, long p_157057_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL11.glDrawElements(p_157054_, p_157055_, p_157056_, p_157057_);
|
||||
}
|
||||
|
||||
public static void _pixelStore(int p_84523_, int p_84524_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GL11.glPixelStorei(p_84523_, p_84524_);
|
||||
}
|
||||
|
||||
public static void _readPixels(int p_84220_, int p_84221_, int p_84222_, int p_84223_, int p_84224_, int p_84225_, ByteBuffer p_84226_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL11.glReadPixels(p_84220_, p_84221_, p_84222_, p_84223_, p_84224_, p_84225_, p_84226_);
|
||||
}
|
||||
|
||||
public static void _readPixels(int p_157101_, int p_157102_, int p_157103_, int p_157104_, int p_157105_, int p_157106_, long p_157107_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GL11.glReadPixels(p_157101_, p_157102_, p_157103_, p_157104_, p_157105_, p_157106_, p_157107_);
|
||||
}
|
||||
|
||||
public static int _getError() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
return GL11.glGetError();
|
||||
}
|
||||
|
||||
public static String _getString(int p_84090_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
return GL11.glGetString(p_84090_);
|
||||
}
|
||||
|
||||
public static int _getInteger(int p_84093_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
return GL11.glGetInteger(p_84093_);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class BlendState {
|
||||
public final GlStateManager.BooleanState mode = new GlStateManager.BooleanState(3042);
|
||||
public int srcRgb = 1;
|
||||
public int dstRgb = 0;
|
||||
public int srcAlpha = 1;
|
||||
public int dstAlpha = 0;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class BooleanState {
|
||||
private final int state;
|
||||
private boolean enabled;
|
||||
|
||||
public BooleanState(int p_84588_) {
|
||||
this.state = p_84588_;
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
this.setEnabled(false);
|
||||
}
|
||||
|
||||
public void enable() {
|
||||
this.setEnabled(true);
|
||||
}
|
||||
|
||||
public void setEnabled(boolean p_84591_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
if (p_84591_ != this.enabled) {
|
||||
this.enabled = p_84591_;
|
||||
if (p_84591_) {
|
||||
GL11.glEnable(this.state);
|
||||
} else {
|
||||
GL11.glDisable(this.state);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class ColorLogicState {
|
||||
public final GlStateManager.BooleanState enable = new GlStateManager.BooleanState(3058);
|
||||
public int op = 5379;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class ColorMask {
|
||||
public boolean red = true;
|
||||
public boolean green = true;
|
||||
public boolean blue = true;
|
||||
public boolean alpha = true;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class CullState {
|
||||
public final GlStateManager.BooleanState enable = new GlStateManager.BooleanState(2884);
|
||||
public int mode = 1029;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class DepthState {
|
||||
public final GlStateManager.BooleanState mode = new GlStateManager.BooleanState(2929);
|
||||
public boolean mask = true;
|
||||
public int func = 513;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@DontObfuscate
|
||||
public static enum DestFactor {
|
||||
CONSTANT_ALPHA(32771),
|
||||
CONSTANT_COLOR(32769),
|
||||
DST_ALPHA(772),
|
||||
DST_COLOR(774),
|
||||
ONE(1),
|
||||
ONE_MINUS_CONSTANT_ALPHA(32772),
|
||||
ONE_MINUS_CONSTANT_COLOR(32770),
|
||||
ONE_MINUS_DST_ALPHA(773),
|
||||
ONE_MINUS_DST_COLOR(775),
|
||||
ONE_MINUS_SRC_ALPHA(771),
|
||||
ONE_MINUS_SRC_COLOR(769),
|
||||
SRC_ALPHA(770),
|
||||
SRC_COLOR(768),
|
||||
ZERO(0);
|
||||
|
||||
public final int value;
|
||||
|
||||
private DestFactor(int p_84652_) {
|
||||
this.value = p_84652_;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum LogicOp {
|
||||
AND(5377),
|
||||
AND_INVERTED(5380),
|
||||
AND_REVERSE(5378),
|
||||
CLEAR(5376),
|
||||
COPY(5379),
|
||||
COPY_INVERTED(5388),
|
||||
EQUIV(5385),
|
||||
INVERT(5386),
|
||||
NAND(5390),
|
||||
NOOP(5381),
|
||||
NOR(5384),
|
||||
OR(5383),
|
||||
OR_INVERTED(5389),
|
||||
OR_REVERSE(5387),
|
||||
SET(5391),
|
||||
XOR(5382);
|
||||
|
||||
public final int value;
|
||||
|
||||
private LogicOp(int p_84721_) {
|
||||
this.value = p_84721_;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class PolygonOffsetState {
|
||||
public final GlStateManager.BooleanState fill = new GlStateManager.BooleanState(32823);
|
||||
public final GlStateManager.BooleanState line = new GlStateManager.BooleanState(10754);
|
||||
public float factor;
|
||||
public float units;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class ScissorState {
|
||||
public final GlStateManager.BooleanState mode = new GlStateManager.BooleanState(3089);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@DontObfuscate
|
||||
public static enum SourceFactor {
|
||||
CONSTANT_ALPHA(32771),
|
||||
CONSTANT_COLOR(32769),
|
||||
DST_ALPHA(772),
|
||||
DST_COLOR(774),
|
||||
ONE(1),
|
||||
ONE_MINUS_CONSTANT_ALPHA(32772),
|
||||
ONE_MINUS_CONSTANT_COLOR(32770),
|
||||
ONE_MINUS_DST_ALPHA(773),
|
||||
ONE_MINUS_DST_COLOR(775),
|
||||
ONE_MINUS_SRC_ALPHA(771),
|
||||
ONE_MINUS_SRC_COLOR(769),
|
||||
SRC_ALPHA(770),
|
||||
SRC_ALPHA_SATURATE(776),
|
||||
SRC_COLOR(768),
|
||||
ZERO(0);
|
||||
|
||||
public final int value;
|
||||
|
||||
private SourceFactor(int p_84757_) {
|
||||
this.value = p_84757_;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class StencilFunc {
|
||||
public int func = 519;
|
||||
public int ref;
|
||||
public int mask = -1;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class StencilState {
|
||||
public final GlStateManager.StencilFunc func = new GlStateManager.StencilFunc();
|
||||
public int mask = -1;
|
||||
public int fail = 7680;
|
||||
public int zfail = 7680;
|
||||
public int zpass = 7680;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class TextureState {
|
||||
public int binding;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum Viewport {
|
||||
INSTANCE;
|
||||
|
||||
protected int x;
|
||||
protected int y;
|
||||
protected int width;
|
||||
protected int height;
|
||||
|
||||
public static int x() {
|
||||
return INSTANCE.x;
|
||||
}
|
||||
|
||||
public static int y() {
|
||||
return INSTANCE.y;
|
||||
}
|
||||
|
||||
public static int width() {
|
||||
return INSTANCE.width;
|
||||
}
|
||||
|
||||
public static int height() {
|
||||
return INSTANCE.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.mojang.blaze3d.platform;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class GlUtil {
|
||||
public static ByteBuffer allocateMemory(int p_166248_) {
|
||||
return MemoryUtil.memAlloc(p_166248_);
|
||||
}
|
||||
|
||||
public static void freeMemory(Buffer p_166252_) {
|
||||
MemoryUtil.memFree(p_166252_);
|
||||
}
|
||||
|
||||
public static String getVendor() {
|
||||
return GlStateManager._getString(7936);
|
||||
}
|
||||
|
||||
public static String getCpuInfo() {
|
||||
return GLX._getCpuInfo();
|
||||
}
|
||||
|
||||
public static String getRenderer() {
|
||||
return GlStateManager._getString(7937);
|
||||
}
|
||||
|
||||
public static String getOpenGLVersion() {
|
||||
return GlStateManager._getString(7938);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.mojang.blaze3d.platform;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import net.minecraft.server.packs.PackResources;
|
||||
import net.minecraft.server.packs.resources.IoSupplier;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public enum IconSet {
|
||||
RELEASE("icons"),
|
||||
SNAPSHOT("icons", "snapshot");
|
||||
|
||||
private final String[] path;
|
||||
|
||||
private IconSet(String... p_281663_) {
|
||||
this.path = p_281663_;
|
||||
}
|
||||
|
||||
public List<IoSupplier<InputStream>> getStandardIcons(PackResources p_281372_) throws IOException {
|
||||
return List.of(this.getFile(p_281372_, "icon_16x16.png"), this.getFile(p_281372_, "icon_32x32.png"), this.getFile(p_281372_, "icon_48x48.png"), this.getFile(p_281372_, "icon_128x128.png"), this.getFile(p_281372_, "icon_256x256.png"));
|
||||
}
|
||||
|
||||
public IoSupplier<InputStream> getMacIcon(PackResources p_281289_) throws IOException {
|
||||
return this.getFile(p_281289_, "minecraft.icns");
|
||||
}
|
||||
|
||||
private IoSupplier<InputStream> getFile(PackResources p_281570_, String p_281345_) throws IOException {
|
||||
String[] astring = ArrayUtils.add(this.path, p_281345_);
|
||||
IoSupplier<InputStream> iosupplier = p_281570_.getRootResource(astring);
|
||||
if (iosupplier == null) {
|
||||
throw new FileNotFoundException(String.join("/", astring));
|
||||
} else {
|
||||
return iosupplier;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,479 @@
|
||||
package com.mojang.blaze3d.platform;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.function.BiFunction;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.locale.Language;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.util.LazyLoadedValue;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.glfw.GLFWCharModsCallbackI;
|
||||
import org.lwjgl.glfw.GLFWCursorPosCallbackI;
|
||||
import org.lwjgl.glfw.GLFWDropCallbackI;
|
||||
import org.lwjgl.glfw.GLFWKeyCallbackI;
|
||||
import org.lwjgl.glfw.GLFWMouseButtonCallbackI;
|
||||
import org.lwjgl.glfw.GLFWScrollCallbackI;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class InputConstants {
|
||||
@Nullable
|
||||
private static final MethodHandle GLFW_RAW_MOUSE_MOTION_SUPPORTED;
|
||||
private static final int GLFW_RAW_MOUSE_MOTION;
|
||||
public static final int KEY_0 = 48;
|
||||
public static final int KEY_1 = 49;
|
||||
public static final int KEY_2 = 50;
|
||||
public static final int KEY_3 = 51;
|
||||
public static final int KEY_4 = 52;
|
||||
public static final int KEY_5 = 53;
|
||||
public static final int KEY_6 = 54;
|
||||
public static final int KEY_7 = 55;
|
||||
public static final int KEY_8 = 56;
|
||||
public static final int KEY_9 = 57;
|
||||
public static final int KEY_A = 65;
|
||||
public static final int KEY_B = 66;
|
||||
public static final int KEY_C = 67;
|
||||
public static final int KEY_D = 68;
|
||||
public static final int KEY_E = 69;
|
||||
public static final int KEY_F = 70;
|
||||
public static final int KEY_G = 71;
|
||||
public static final int KEY_H = 72;
|
||||
public static final int KEY_I = 73;
|
||||
public static final int KEY_J = 74;
|
||||
public static final int KEY_K = 75;
|
||||
public static final int KEY_L = 76;
|
||||
public static final int KEY_M = 77;
|
||||
public static final int KEY_N = 78;
|
||||
public static final int KEY_O = 79;
|
||||
public static final int KEY_P = 80;
|
||||
public static final int KEY_Q = 81;
|
||||
public static final int KEY_R = 82;
|
||||
public static final int KEY_S = 83;
|
||||
public static final int KEY_T = 84;
|
||||
public static final int KEY_U = 85;
|
||||
public static final int KEY_V = 86;
|
||||
public static final int KEY_W = 87;
|
||||
public static final int KEY_X = 88;
|
||||
public static final int KEY_Y = 89;
|
||||
public static final int KEY_Z = 90;
|
||||
public static final int KEY_F1 = 290;
|
||||
public static final int KEY_F2 = 291;
|
||||
public static final int KEY_F3 = 292;
|
||||
public static final int KEY_F4 = 293;
|
||||
public static final int KEY_F5 = 294;
|
||||
public static final int KEY_F6 = 295;
|
||||
public static final int KEY_F7 = 296;
|
||||
public static final int KEY_F8 = 297;
|
||||
public static final int KEY_F9 = 298;
|
||||
public static final int KEY_F10 = 299;
|
||||
public static final int KEY_F11 = 300;
|
||||
public static final int KEY_F12 = 301;
|
||||
public static final int KEY_F13 = 302;
|
||||
public static final int KEY_F14 = 303;
|
||||
public static final int KEY_F15 = 304;
|
||||
public static final int KEY_F16 = 305;
|
||||
public static final int KEY_F17 = 306;
|
||||
public static final int KEY_F18 = 307;
|
||||
public static final int KEY_F19 = 308;
|
||||
public static final int KEY_F20 = 309;
|
||||
public static final int KEY_F21 = 310;
|
||||
public static final int KEY_F22 = 311;
|
||||
public static final int KEY_F23 = 312;
|
||||
public static final int KEY_F24 = 313;
|
||||
public static final int KEY_F25 = 314;
|
||||
public static final int KEY_NUMLOCK = 282;
|
||||
public static final int KEY_NUMPAD0 = 320;
|
||||
public static final int KEY_NUMPAD1 = 321;
|
||||
public static final int KEY_NUMPAD2 = 322;
|
||||
public static final int KEY_NUMPAD3 = 323;
|
||||
public static final int KEY_NUMPAD4 = 324;
|
||||
public static final int KEY_NUMPAD5 = 325;
|
||||
public static final int KEY_NUMPAD6 = 326;
|
||||
public static final int KEY_NUMPAD7 = 327;
|
||||
public static final int KEY_NUMPAD8 = 328;
|
||||
public static final int KEY_NUMPAD9 = 329;
|
||||
public static final int KEY_NUMPADCOMMA = 330;
|
||||
public static final int KEY_NUMPADENTER = 335;
|
||||
public static final int KEY_NUMPADEQUALS = 336;
|
||||
public static final int KEY_DOWN = 264;
|
||||
public static final int KEY_LEFT = 263;
|
||||
public static final int KEY_RIGHT = 262;
|
||||
public static final int KEY_UP = 265;
|
||||
public static final int KEY_ADD = 334;
|
||||
public static final int KEY_APOSTROPHE = 39;
|
||||
public static final int KEY_BACKSLASH = 92;
|
||||
public static final int KEY_COMMA = 44;
|
||||
public static final int KEY_EQUALS = 61;
|
||||
public static final int KEY_GRAVE = 96;
|
||||
public static final int KEY_LBRACKET = 91;
|
||||
public static final int KEY_MINUS = 45;
|
||||
public static final int KEY_MULTIPLY = 332;
|
||||
public static final int KEY_PERIOD = 46;
|
||||
public static final int KEY_RBRACKET = 93;
|
||||
public static final int KEY_SEMICOLON = 59;
|
||||
public static final int KEY_SLASH = 47;
|
||||
public static final int KEY_SPACE = 32;
|
||||
public static final int KEY_TAB = 258;
|
||||
public static final int KEY_LALT = 342;
|
||||
public static final int KEY_LCONTROL = 341;
|
||||
public static final int KEY_LSHIFT = 340;
|
||||
public static final int KEY_LWIN = 343;
|
||||
public static final int KEY_RALT = 346;
|
||||
public static final int KEY_RCONTROL = 345;
|
||||
public static final int KEY_RSHIFT = 344;
|
||||
public static final int KEY_RWIN = 347;
|
||||
public static final int KEY_RETURN = 257;
|
||||
public static final int KEY_ESCAPE = 256;
|
||||
public static final int KEY_BACKSPACE = 259;
|
||||
public static final int KEY_DELETE = 261;
|
||||
public static final int KEY_END = 269;
|
||||
public static final int KEY_HOME = 268;
|
||||
public static final int KEY_INSERT = 260;
|
||||
public static final int KEY_PAGEDOWN = 267;
|
||||
public static final int KEY_PAGEUP = 266;
|
||||
public static final int KEY_CAPSLOCK = 280;
|
||||
public static final int KEY_PAUSE = 284;
|
||||
public static final int KEY_SCROLLLOCK = 281;
|
||||
public static final int KEY_PRINTSCREEN = 283;
|
||||
public static final int PRESS = 1;
|
||||
public static final int RELEASE = 0;
|
||||
public static final int REPEAT = 2;
|
||||
public static final int MOUSE_BUTTON_LEFT = 0;
|
||||
public static final int MOUSE_BUTTON_MIDDLE = 2;
|
||||
public static final int MOUSE_BUTTON_RIGHT = 1;
|
||||
public static final int MOD_CONTROL = 2;
|
||||
public static final int CURSOR = 208897;
|
||||
public static final int CURSOR_DISABLED = 212995;
|
||||
public static final int CURSOR_NORMAL = 212993;
|
||||
public static final InputConstants.Key UNKNOWN;
|
||||
|
||||
public static InputConstants.Key getKey(int p_84828_, int p_84829_) {
|
||||
return p_84828_ == -1 ? InputConstants.Type.SCANCODE.getOrCreate(p_84829_) : InputConstants.Type.KEYSYM.getOrCreate(p_84828_);
|
||||
}
|
||||
|
||||
public static InputConstants.Key getKey(String p_84852_) {
|
||||
if (InputConstants.Key.NAME_MAP.containsKey(p_84852_)) {
|
||||
return InputConstants.Key.NAME_MAP.get(p_84852_);
|
||||
} else {
|
||||
for(InputConstants.Type inputconstants$type : InputConstants.Type.values()) {
|
||||
if (p_84852_.startsWith(inputconstants$type.defaultPrefix)) {
|
||||
String s = p_84852_.substring(inputconstants$type.defaultPrefix.length() + 1);
|
||||
int i = Integer.parseInt(s);
|
||||
if (inputconstants$type == InputConstants.Type.MOUSE) {
|
||||
--i;
|
||||
}
|
||||
|
||||
return inputconstants$type.getOrCreate(i);
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unknown key name: " + p_84852_);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isKeyDown(long p_84831_, int p_84832_) {
|
||||
return GLFW.glfwGetKey(p_84831_, p_84832_) == 1;
|
||||
}
|
||||
|
||||
public static void setupKeyboardCallbacks(long p_84845_, GLFWKeyCallbackI p_84846_, GLFWCharModsCallbackI p_84847_) {
|
||||
GLFW.glfwSetKeyCallback(p_84845_, p_84846_);
|
||||
GLFW.glfwSetCharModsCallback(p_84845_, p_84847_);
|
||||
}
|
||||
|
||||
public static void setupMouseCallbacks(long p_84839_, GLFWCursorPosCallbackI p_84840_, GLFWMouseButtonCallbackI p_84841_, GLFWScrollCallbackI p_84842_, GLFWDropCallbackI p_84843_) {
|
||||
GLFW.glfwSetCursorPosCallback(p_84839_, p_84840_);
|
||||
GLFW.glfwSetMouseButtonCallback(p_84839_, p_84841_);
|
||||
GLFW.glfwSetScrollCallback(p_84839_, p_84842_);
|
||||
GLFW.glfwSetDropCallback(p_84839_, p_84843_);
|
||||
}
|
||||
|
||||
public static void grabOrReleaseMouse(long p_84834_, int p_84835_, double p_84836_, double p_84837_) {
|
||||
GLFW.glfwSetCursorPos(p_84834_, p_84836_, p_84837_);
|
||||
GLFW.glfwSetInputMode(p_84834_, 208897, p_84835_);
|
||||
}
|
||||
|
||||
public static boolean isRawMouseInputSupported() {
|
||||
try {
|
||||
return GLFW_RAW_MOUSE_MOTION_SUPPORTED != null && (boolean)GLFW_RAW_MOUSE_MOTION_SUPPORTED.invokeExact();
|
||||
} catch (Throwable throwable) {
|
||||
throw new RuntimeException(throwable);
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateRawMouseInput(long p_84849_, boolean p_84850_) {
|
||||
if (isRawMouseInputSupported()) {
|
||||
GLFW.glfwSetInputMode(p_84849_, GLFW_RAW_MOUSE_MOTION, p_84850_ ? 1 : 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static {
|
||||
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||
MethodType methodtype = MethodType.methodType(Boolean.TYPE);
|
||||
MethodHandle methodhandle = null;
|
||||
int i = 0;
|
||||
|
||||
try {
|
||||
methodhandle = lookup.findStatic(GLFW.class, "glfwRawMouseMotionSupported", methodtype);
|
||||
MethodHandle methodhandle1 = lookup.findStaticGetter(GLFW.class, "GLFW_RAW_MOUSE_MOTION", Integer.TYPE);
|
||||
i = (int)methodhandle1.invokeExact();
|
||||
} catch (NoSuchFieldException | NoSuchMethodException nosuchmethodexception) {
|
||||
} catch (Throwable throwable) {
|
||||
throw new RuntimeException(throwable);
|
||||
}
|
||||
|
||||
GLFW_RAW_MOUSE_MOTION_SUPPORTED = methodhandle;
|
||||
GLFW_RAW_MOUSE_MOTION = i;
|
||||
UNKNOWN = InputConstants.Type.KEYSYM.getOrCreate(-1);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static final class Key {
|
||||
private final String name;
|
||||
private final InputConstants.Type type;
|
||||
private final int value;
|
||||
private final LazyLoadedValue<Component> displayName;
|
||||
static final Map<String, InputConstants.Key> NAME_MAP = Maps.newHashMap();
|
||||
|
||||
Key(String p_84860_, InputConstants.Type p_84861_, int p_84862_) {
|
||||
this.name = p_84860_;
|
||||
this.type = p_84861_;
|
||||
this.value = p_84862_;
|
||||
this.displayName = new LazyLoadedValue<>(() -> {
|
||||
return p_84861_.displayTextSupplier.apply(p_84862_, p_84860_);
|
||||
});
|
||||
NAME_MAP.put(p_84860_, this);
|
||||
}
|
||||
|
||||
public InputConstants.Type getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public Component getDisplayName() {
|
||||
return this.displayName.get();
|
||||
}
|
||||
|
||||
public OptionalInt getNumericKeyValue() {
|
||||
if (this.value >= 48 && this.value <= 57) {
|
||||
return OptionalInt.of(this.value - 48);
|
||||
} else {
|
||||
return this.value >= 320 && this.value <= 329 ? OptionalInt.of(this.value - 320) : OptionalInt.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean equals(Object p_84878_) {
|
||||
if (this == p_84878_) {
|
||||
return true;
|
||||
} else if (p_84878_ != null && this.getClass() == p_84878_.getClass()) {
|
||||
InputConstants.Key inputconstants$key = (InputConstants.Key)p_84878_;
|
||||
return this.value == inputconstants$key.value && this.type == inputconstants$key.type;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.type, this.value);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum Type {
|
||||
KEYSYM("key.keyboard", (p_288232_, p_288233_) -> {
|
||||
if ("key.keyboard.unknown".equals(p_288233_)) {
|
||||
return Component.translatable(p_288233_);
|
||||
} else {
|
||||
String s = GLFW.glfwGetKeyName(p_288232_, -1);
|
||||
return s != null ? Component.literal(s.toUpperCase(Locale.ROOT)) : Component.translatable(p_288233_);
|
||||
}
|
||||
}),
|
||||
SCANCODE("scancode", (p_84911_, p_84912_) -> {
|
||||
String s = GLFW.glfwGetKeyName(-1, p_84911_);
|
||||
return s != null ? Component.literal(s) : Component.translatable(p_84912_);
|
||||
}),
|
||||
MOUSE("key.mouse", (p_84904_, p_84905_) -> {
|
||||
return Language.getInstance().has(p_84905_) ? Component.translatable(p_84905_) : Component.translatable("key.mouse", p_84904_ + 1);
|
||||
});
|
||||
|
||||
private static final String KEY_KEYBOARD_UNKNOWN = "key.keyboard.unknown";
|
||||
private final Int2ObjectMap<InputConstants.Key> map = new Int2ObjectOpenHashMap<>();
|
||||
final String defaultPrefix;
|
||||
final BiFunction<Integer, String, Component> displayTextSupplier;
|
||||
|
||||
private static void addKey(InputConstants.Type p_84900_, String p_84901_, int p_84902_) {
|
||||
InputConstants.Key inputconstants$key = new InputConstants.Key(p_84901_, p_84900_, p_84902_);
|
||||
p_84900_.map.put(p_84902_, inputconstants$key);
|
||||
}
|
||||
|
||||
private Type(String p_84893_, BiFunction<Integer, String, Component> p_84894_) {
|
||||
this.defaultPrefix = p_84893_;
|
||||
this.displayTextSupplier = p_84894_;
|
||||
}
|
||||
|
||||
public InputConstants.Key getOrCreate(int p_84896_) {
|
||||
return this.map.computeIfAbsent(p_84896_, (p_84907_) -> {
|
||||
int i = p_84907_;
|
||||
if (this == MOUSE) {
|
||||
i = p_84907_ + 1;
|
||||
}
|
||||
|
||||
String s = this.defaultPrefix + "." + i;
|
||||
return new InputConstants.Key(s, this, p_84907_);
|
||||
});
|
||||
}
|
||||
|
||||
static {
|
||||
addKey(KEYSYM, "key.keyboard.unknown", -1);
|
||||
addKey(MOUSE, "key.mouse.left", 0);
|
||||
addKey(MOUSE, "key.mouse.right", 1);
|
||||
addKey(MOUSE, "key.mouse.middle", 2);
|
||||
addKey(MOUSE, "key.mouse.4", 3);
|
||||
addKey(MOUSE, "key.mouse.5", 4);
|
||||
addKey(MOUSE, "key.mouse.6", 5);
|
||||
addKey(MOUSE, "key.mouse.7", 6);
|
||||
addKey(MOUSE, "key.mouse.8", 7);
|
||||
addKey(KEYSYM, "key.keyboard.0", 48);
|
||||
addKey(KEYSYM, "key.keyboard.1", 49);
|
||||
addKey(KEYSYM, "key.keyboard.2", 50);
|
||||
addKey(KEYSYM, "key.keyboard.3", 51);
|
||||
addKey(KEYSYM, "key.keyboard.4", 52);
|
||||
addKey(KEYSYM, "key.keyboard.5", 53);
|
||||
addKey(KEYSYM, "key.keyboard.6", 54);
|
||||
addKey(KEYSYM, "key.keyboard.7", 55);
|
||||
addKey(KEYSYM, "key.keyboard.8", 56);
|
||||
addKey(KEYSYM, "key.keyboard.9", 57);
|
||||
addKey(KEYSYM, "key.keyboard.a", 65);
|
||||
addKey(KEYSYM, "key.keyboard.b", 66);
|
||||
addKey(KEYSYM, "key.keyboard.c", 67);
|
||||
addKey(KEYSYM, "key.keyboard.d", 68);
|
||||
addKey(KEYSYM, "key.keyboard.e", 69);
|
||||
addKey(KEYSYM, "key.keyboard.f", 70);
|
||||
addKey(KEYSYM, "key.keyboard.g", 71);
|
||||
addKey(KEYSYM, "key.keyboard.h", 72);
|
||||
addKey(KEYSYM, "key.keyboard.i", 73);
|
||||
addKey(KEYSYM, "key.keyboard.j", 74);
|
||||
addKey(KEYSYM, "key.keyboard.k", 75);
|
||||
addKey(KEYSYM, "key.keyboard.l", 76);
|
||||
addKey(KEYSYM, "key.keyboard.m", 77);
|
||||
addKey(KEYSYM, "key.keyboard.n", 78);
|
||||
addKey(KEYSYM, "key.keyboard.o", 79);
|
||||
addKey(KEYSYM, "key.keyboard.p", 80);
|
||||
addKey(KEYSYM, "key.keyboard.q", 81);
|
||||
addKey(KEYSYM, "key.keyboard.r", 82);
|
||||
addKey(KEYSYM, "key.keyboard.s", 83);
|
||||
addKey(KEYSYM, "key.keyboard.t", 84);
|
||||
addKey(KEYSYM, "key.keyboard.u", 85);
|
||||
addKey(KEYSYM, "key.keyboard.v", 86);
|
||||
addKey(KEYSYM, "key.keyboard.w", 87);
|
||||
addKey(KEYSYM, "key.keyboard.x", 88);
|
||||
addKey(KEYSYM, "key.keyboard.y", 89);
|
||||
addKey(KEYSYM, "key.keyboard.z", 90);
|
||||
addKey(KEYSYM, "key.keyboard.f1", 290);
|
||||
addKey(KEYSYM, "key.keyboard.f2", 291);
|
||||
addKey(KEYSYM, "key.keyboard.f3", 292);
|
||||
addKey(KEYSYM, "key.keyboard.f4", 293);
|
||||
addKey(KEYSYM, "key.keyboard.f5", 294);
|
||||
addKey(KEYSYM, "key.keyboard.f6", 295);
|
||||
addKey(KEYSYM, "key.keyboard.f7", 296);
|
||||
addKey(KEYSYM, "key.keyboard.f8", 297);
|
||||
addKey(KEYSYM, "key.keyboard.f9", 298);
|
||||
addKey(KEYSYM, "key.keyboard.f10", 299);
|
||||
addKey(KEYSYM, "key.keyboard.f11", 300);
|
||||
addKey(KEYSYM, "key.keyboard.f12", 301);
|
||||
addKey(KEYSYM, "key.keyboard.f13", 302);
|
||||
addKey(KEYSYM, "key.keyboard.f14", 303);
|
||||
addKey(KEYSYM, "key.keyboard.f15", 304);
|
||||
addKey(KEYSYM, "key.keyboard.f16", 305);
|
||||
addKey(KEYSYM, "key.keyboard.f17", 306);
|
||||
addKey(KEYSYM, "key.keyboard.f18", 307);
|
||||
addKey(KEYSYM, "key.keyboard.f19", 308);
|
||||
addKey(KEYSYM, "key.keyboard.f20", 309);
|
||||
addKey(KEYSYM, "key.keyboard.f21", 310);
|
||||
addKey(KEYSYM, "key.keyboard.f22", 311);
|
||||
addKey(KEYSYM, "key.keyboard.f23", 312);
|
||||
addKey(KEYSYM, "key.keyboard.f24", 313);
|
||||
addKey(KEYSYM, "key.keyboard.f25", 314);
|
||||
addKey(KEYSYM, "key.keyboard.num.lock", 282);
|
||||
addKey(KEYSYM, "key.keyboard.keypad.0", 320);
|
||||
addKey(KEYSYM, "key.keyboard.keypad.1", 321);
|
||||
addKey(KEYSYM, "key.keyboard.keypad.2", 322);
|
||||
addKey(KEYSYM, "key.keyboard.keypad.3", 323);
|
||||
addKey(KEYSYM, "key.keyboard.keypad.4", 324);
|
||||
addKey(KEYSYM, "key.keyboard.keypad.5", 325);
|
||||
addKey(KEYSYM, "key.keyboard.keypad.6", 326);
|
||||
addKey(KEYSYM, "key.keyboard.keypad.7", 327);
|
||||
addKey(KEYSYM, "key.keyboard.keypad.8", 328);
|
||||
addKey(KEYSYM, "key.keyboard.keypad.9", 329);
|
||||
addKey(KEYSYM, "key.keyboard.keypad.add", 334);
|
||||
addKey(KEYSYM, "key.keyboard.keypad.decimal", 330);
|
||||
addKey(KEYSYM, "key.keyboard.keypad.enter", 335);
|
||||
addKey(KEYSYM, "key.keyboard.keypad.equal", 336);
|
||||
addKey(KEYSYM, "key.keyboard.keypad.multiply", 332);
|
||||
addKey(KEYSYM, "key.keyboard.keypad.divide", 331);
|
||||
addKey(KEYSYM, "key.keyboard.keypad.subtract", 333);
|
||||
addKey(KEYSYM, "key.keyboard.down", 264);
|
||||
addKey(KEYSYM, "key.keyboard.left", 263);
|
||||
addKey(KEYSYM, "key.keyboard.right", 262);
|
||||
addKey(KEYSYM, "key.keyboard.up", 265);
|
||||
addKey(KEYSYM, "key.keyboard.apostrophe", 39);
|
||||
addKey(KEYSYM, "key.keyboard.backslash", 92);
|
||||
addKey(KEYSYM, "key.keyboard.comma", 44);
|
||||
addKey(KEYSYM, "key.keyboard.equal", 61);
|
||||
addKey(KEYSYM, "key.keyboard.grave.accent", 96);
|
||||
addKey(KEYSYM, "key.keyboard.left.bracket", 91);
|
||||
addKey(KEYSYM, "key.keyboard.minus", 45);
|
||||
addKey(KEYSYM, "key.keyboard.period", 46);
|
||||
addKey(KEYSYM, "key.keyboard.right.bracket", 93);
|
||||
addKey(KEYSYM, "key.keyboard.semicolon", 59);
|
||||
addKey(KEYSYM, "key.keyboard.slash", 47);
|
||||
addKey(KEYSYM, "key.keyboard.space", 32);
|
||||
addKey(KEYSYM, "key.keyboard.tab", 258);
|
||||
addKey(KEYSYM, "key.keyboard.left.alt", 342);
|
||||
addKey(KEYSYM, "key.keyboard.left.control", 341);
|
||||
addKey(KEYSYM, "key.keyboard.left.shift", 340);
|
||||
addKey(KEYSYM, "key.keyboard.left.win", 343);
|
||||
addKey(KEYSYM, "key.keyboard.right.alt", 346);
|
||||
addKey(KEYSYM, "key.keyboard.right.control", 345);
|
||||
addKey(KEYSYM, "key.keyboard.right.shift", 344);
|
||||
addKey(KEYSYM, "key.keyboard.right.win", 347);
|
||||
addKey(KEYSYM, "key.keyboard.enter", 257);
|
||||
addKey(KEYSYM, "key.keyboard.escape", 256);
|
||||
addKey(KEYSYM, "key.keyboard.backspace", 259);
|
||||
addKey(KEYSYM, "key.keyboard.delete", 261);
|
||||
addKey(KEYSYM, "key.keyboard.end", 269);
|
||||
addKey(KEYSYM, "key.keyboard.home", 268);
|
||||
addKey(KEYSYM, "key.keyboard.insert", 260);
|
||||
addKey(KEYSYM, "key.keyboard.page.down", 267);
|
||||
addKey(KEYSYM, "key.keyboard.page.up", 266);
|
||||
addKey(KEYSYM, "key.keyboard.caps.lock", 280);
|
||||
addKey(KEYSYM, "key.keyboard.pause", 284);
|
||||
addKey(KEYSYM, "key.keyboard.scroll.lock", 281);
|
||||
addKey(KEYSYM, "key.keyboard.menu", 348);
|
||||
addKey(KEYSYM, "key.keyboard.print.screen", 283);
|
||||
addKey(KEYSYM, "key.keyboard.world.1", 161);
|
||||
addKey(KEYSYM, "key.keyboard.world.2", 162);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.mojang.blaze3d.platform;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class Lighting {
|
||||
private static final Vector3f DIFFUSE_LIGHT_0 = (new Vector3f(0.2F, 1.0F, -0.7F)).normalize();
|
||||
private static final Vector3f DIFFUSE_LIGHT_1 = (new Vector3f(-0.2F, 1.0F, 0.7F)).normalize();
|
||||
private static final Vector3f NETHER_DIFFUSE_LIGHT_0 = (new Vector3f(0.2F, 1.0F, -0.7F)).normalize();
|
||||
private static final Vector3f NETHER_DIFFUSE_LIGHT_1 = (new Vector3f(-0.2F, -1.0F, 0.7F)).normalize();
|
||||
private static final Vector3f INVENTORY_DIFFUSE_LIGHT_0 = (new Vector3f(0.2F, -1.0F, -1.0F)).normalize();
|
||||
private static final Vector3f INVENTORY_DIFFUSE_LIGHT_1 = (new Vector3f(-0.2F, -1.0F, 0.0F)).normalize();
|
||||
|
||||
public static void setupNetherLevel(Matrix4f p_254421_) {
|
||||
RenderSystem.setupLevelDiffuseLighting(NETHER_DIFFUSE_LIGHT_0, NETHER_DIFFUSE_LIGHT_1, p_254421_);
|
||||
}
|
||||
|
||||
public static void setupLevel(Matrix4f p_254246_) {
|
||||
RenderSystem.setupLevelDiffuseLighting(DIFFUSE_LIGHT_0, DIFFUSE_LIGHT_1, p_254246_);
|
||||
}
|
||||
|
||||
public static void setupForFlatItems() {
|
||||
RenderSystem.setupGuiFlatDiffuseLighting(DIFFUSE_LIGHT_0, DIFFUSE_LIGHT_1);
|
||||
}
|
||||
|
||||
public static void setupFor3DItems() {
|
||||
RenderSystem.setupGui3DDiffuseLighting(DIFFUSE_LIGHT_0, DIFFUSE_LIGHT_1);
|
||||
}
|
||||
|
||||
public static void setupForEntityInInventory() {
|
||||
RenderSystem.setShaderLights(INVENTORY_DIFFUSE_LIGHT_0, INVENTORY_DIFFUSE_LIGHT_1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.mojang.blaze3d.platform;
|
||||
|
||||
import ca.weblite.objc.Client;
|
||||
import ca.weblite.objc.NSObject;
|
||||
import com.sun.jna.Pointer;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Base64;
|
||||
import java.util.Optional;
|
||||
import net.minecraft.server.packs.resources.IoSupplier;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.glfw.GLFWNativeCocoa;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class MacosUtil {
|
||||
private static final int NS_FULL_SCREEN_WINDOW_MASK = 16384;
|
||||
|
||||
public static void toggleFullscreen(long p_182518_) {
|
||||
getNsWindow(p_182518_).filter(MacosUtil::isInKioskMode).ifPresent(MacosUtil::toggleFullscreen);
|
||||
}
|
||||
|
||||
private static Optional<NSObject> getNsWindow(long p_182522_) {
|
||||
long i = GLFWNativeCocoa.glfwGetCocoaWindow(p_182522_);
|
||||
return i != 0L ? Optional.of(new NSObject(new Pointer(i))) : Optional.empty();
|
||||
}
|
||||
|
||||
private static boolean isInKioskMode(NSObject p_182520_) {
|
||||
return (((Number)p_182520_.sendRaw("styleMask", new Object[0])).longValue() & 16384L) == 16384L;
|
||||
}
|
||||
|
||||
private static void toggleFullscreen(NSObject p_182524_) {
|
||||
p_182524_.send("toggleFullScreen:", new Object[]{Pointer.NULL});
|
||||
}
|
||||
|
||||
public static void loadIcon(IoSupplier<InputStream> p_250929_) throws IOException {
|
||||
try (InputStream inputstream = p_250929_.get()) {
|
||||
String s = Base64.getEncoder().encodeToString(inputstream.readAllBytes());
|
||||
Client client = Client.getInstance();
|
||||
Object object = client.sendProxy("NSData", "alloc").send("initWithBase64Encoding:", s);
|
||||
Object object1 = client.sendProxy("NSImage", "alloc").send("initWithData:", object);
|
||||
client.sendProxy("NSApplication", "sharedApplication").send("setApplicationIconImage:", object1);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.mojang.blaze3d.platform;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class MemoryTracker {
|
||||
private static final MemoryUtil.MemoryAllocator ALLOCATOR = MemoryUtil.getAllocator(false);
|
||||
|
||||
public static ByteBuffer create(int p_182528_) {
|
||||
long i = ALLOCATOR.malloc((long)p_182528_);
|
||||
if (i == 0L) {
|
||||
throw new OutOfMemoryError("Failed to allocate " + p_182528_ + " bytes");
|
||||
} else {
|
||||
return MemoryUtil.memByteBuffer(i, p_182528_);
|
||||
}
|
||||
}
|
||||
|
||||
public static ByteBuffer resize(ByteBuffer p_182530_, int p_182531_) {
|
||||
long i = ALLOCATOR.realloc(MemoryUtil.memAddress0(p_182530_), (long)p_182531_);
|
||||
if (i == 0L) {
|
||||
throw new OutOfMemoryError("Failed to resize buffer from " + p_182530_.capacity() + " bytes to " + p_182531_ + " bytes");
|
||||
} else {
|
||||
return MemoryUtil.memByteBuffer(i, p_182531_);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.mojang.blaze3d.platform;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.glfw.GLFWVidMode;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public final class Monitor {
|
||||
private final long monitor;
|
||||
private final List<VideoMode> videoModes;
|
||||
private VideoMode currentMode;
|
||||
private int x;
|
||||
private int y;
|
||||
|
||||
public Monitor(long p_84942_) {
|
||||
this.monitor = p_84942_;
|
||||
this.videoModes = Lists.newArrayList();
|
||||
this.refreshVideoModes();
|
||||
}
|
||||
|
||||
public void refreshVideoModes() {
|
||||
RenderSystem.assertInInitPhase();
|
||||
this.videoModes.clear();
|
||||
GLFWVidMode.Buffer buffer = GLFW.glfwGetVideoModes(this.monitor);
|
||||
|
||||
for(int i = buffer.limit() - 1; i >= 0; --i) {
|
||||
buffer.position(i);
|
||||
VideoMode videomode = new VideoMode(buffer);
|
||||
if (videomode.getRedBits() >= 8 && videomode.getGreenBits() >= 8 && videomode.getBlueBits() >= 8) {
|
||||
this.videoModes.add(videomode);
|
||||
}
|
||||
}
|
||||
|
||||
int[] aint = new int[1];
|
||||
int[] aint1 = new int[1];
|
||||
GLFW.glfwGetMonitorPos(this.monitor, aint, aint1);
|
||||
this.x = aint[0];
|
||||
this.y = aint1[0];
|
||||
GLFWVidMode glfwvidmode = GLFW.glfwGetVideoMode(this.monitor);
|
||||
this.currentMode = new VideoMode(glfwvidmode);
|
||||
}
|
||||
|
||||
public VideoMode getPreferredVidMode(Optional<VideoMode> p_84949_) {
|
||||
RenderSystem.assertInInitPhase();
|
||||
if (p_84949_.isPresent()) {
|
||||
VideoMode videomode = p_84949_.get();
|
||||
|
||||
for(VideoMode videomode1 : this.videoModes) {
|
||||
if (videomode1.equals(videomode)) {
|
||||
return videomode1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.getCurrentMode();
|
||||
}
|
||||
|
||||
public int getVideoModeIndex(VideoMode p_84947_) {
|
||||
RenderSystem.assertInInitPhase();
|
||||
return this.videoModes.indexOf(p_84947_);
|
||||
}
|
||||
|
||||
public VideoMode getCurrentMode() {
|
||||
return this.currentMode;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
public VideoMode getMode(int p_84945_) {
|
||||
return this.videoModes.get(p_84945_);
|
||||
}
|
||||
|
||||
public int getModeCount() {
|
||||
return this.videoModes.size();
|
||||
}
|
||||
|
||||
public long getMonitor() {
|
||||
return this.monitor;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return String.format(Locale.ROOT, "Monitor[%s %sx%s %s]", this.monitor, this.x, this.y, this.currentMode);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.mojang.blaze3d.platform;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface MonitorCreator {
|
||||
Monitor createMonitor(long p_84957_);
|
||||
}
|
||||
@@ -0,0 +1,792 @@
|
||||
package com.mojang.blaze3d.platform;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.function.IntUnaryOperator;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.util.FastColor;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.lwjgl.stb.STBIWriteCallback;
|
||||
import org.lwjgl.stb.STBImage;
|
||||
import org.lwjgl.stb.STBImageResize;
|
||||
import org.lwjgl.stb.STBImageWrite;
|
||||
import org.lwjgl.stb.STBTTFontinfo;
|
||||
import org.lwjgl.stb.STBTruetype;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public final class NativeImage implements AutoCloseable {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final Set<StandardOpenOption> OPEN_OPTIONS = EnumSet.of(StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
|
||||
private final NativeImage.Format format;
|
||||
private final int width;
|
||||
private final int height;
|
||||
private final boolean useStbFree;
|
||||
private long pixels;
|
||||
private final long size;
|
||||
|
||||
public NativeImage(int p_84968_, int p_84969_, boolean p_84970_) {
|
||||
this(NativeImage.Format.RGBA, p_84968_, p_84969_, p_84970_);
|
||||
}
|
||||
|
||||
public NativeImage(NativeImage.Format p_84972_, int p_84973_, int p_84974_, boolean p_84975_) {
|
||||
if (p_84973_ > 0 && p_84974_ > 0) {
|
||||
this.format = p_84972_;
|
||||
this.width = p_84973_;
|
||||
this.height = p_84974_;
|
||||
this.size = (long)p_84973_ * (long)p_84974_ * (long)p_84972_.components();
|
||||
this.useStbFree = false;
|
||||
if (p_84975_) {
|
||||
this.pixels = MemoryUtil.nmemCalloc(1L, this.size);
|
||||
} else {
|
||||
this.pixels = MemoryUtil.nmemAlloc(this.size);
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid texture size: " + p_84973_ + "x" + p_84974_);
|
||||
}
|
||||
}
|
||||
|
||||
private NativeImage(NativeImage.Format p_84977_, int p_84978_, int p_84979_, boolean p_84980_, long p_84981_) {
|
||||
if (p_84978_ > 0 && p_84979_ > 0) {
|
||||
this.format = p_84977_;
|
||||
this.width = p_84978_;
|
||||
this.height = p_84979_;
|
||||
this.useStbFree = p_84980_;
|
||||
this.pixels = p_84981_;
|
||||
this.size = (long)p_84978_ * (long)p_84979_ * (long)p_84977_.components();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid texture size: " + p_84978_ + "x" + p_84979_);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "NativeImage[" + this.format + " " + this.width + "x" + this.height + "@" + this.pixels + (this.useStbFree ? "S" : "N") + "]";
|
||||
}
|
||||
|
||||
private boolean isOutsideBounds(int p_166423_, int p_166424_) {
|
||||
return p_166423_ < 0 || p_166423_ >= this.width || p_166424_ < 0 || p_166424_ >= this.height;
|
||||
}
|
||||
|
||||
public static NativeImage read(InputStream p_85059_) throws IOException {
|
||||
return read(NativeImage.Format.RGBA, p_85059_);
|
||||
}
|
||||
|
||||
public static NativeImage read(@Nullable NativeImage.Format p_85049_, InputStream p_85050_) throws IOException {
|
||||
ByteBuffer bytebuffer = null;
|
||||
|
||||
NativeImage nativeimage;
|
||||
try {
|
||||
bytebuffer = TextureUtil.readResource(p_85050_);
|
||||
bytebuffer.rewind();
|
||||
nativeimage = read(p_85049_, bytebuffer);
|
||||
} finally {
|
||||
MemoryUtil.memFree(bytebuffer);
|
||||
IOUtils.closeQuietly(p_85050_);
|
||||
}
|
||||
|
||||
return nativeimage;
|
||||
}
|
||||
|
||||
public static NativeImage read(ByteBuffer p_85063_) throws IOException {
|
||||
return read(NativeImage.Format.RGBA, p_85063_);
|
||||
}
|
||||
|
||||
public static NativeImage read(byte[] p_273041_) throws IOException {
|
||||
try (MemoryStack memorystack = MemoryStack.stackPush()) {
|
||||
ByteBuffer bytebuffer = memorystack.malloc(p_273041_.length);
|
||||
bytebuffer.put(p_273041_);
|
||||
bytebuffer.rewind();
|
||||
return read(bytebuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public static NativeImage read(@Nullable NativeImage.Format p_85052_, ByteBuffer p_85053_) throws IOException {
|
||||
if (p_85052_ != null && !p_85052_.supportedByStb()) {
|
||||
throw new UnsupportedOperationException("Don't know how to read format " + p_85052_);
|
||||
} else if (MemoryUtil.memAddress(p_85053_) == 0L) {
|
||||
throw new IllegalArgumentException("Invalid buffer");
|
||||
} else {
|
||||
try (MemoryStack memorystack = MemoryStack.stackPush()) {
|
||||
IntBuffer intbuffer = memorystack.mallocInt(1);
|
||||
IntBuffer intbuffer1 = memorystack.mallocInt(1);
|
||||
IntBuffer intbuffer2 = memorystack.mallocInt(1);
|
||||
ByteBuffer bytebuffer = STBImage.stbi_load_from_memory(p_85053_, intbuffer, intbuffer1, intbuffer2, p_85052_ == null ? 0 : p_85052_.components);
|
||||
if (bytebuffer == null) {
|
||||
throw new IOException("Could not load image: " + STBImage.stbi_failure_reason());
|
||||
} else {
|
||||
return new NativeImage(p_85052_ == null ? NativeImage.Format.getStbFormat(intbuffer2.get(0)) : p_85052_, intbuffer.get(0), intbuffer1.get(0), true, MemoryUtil.memAddress(bytebuffer));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void setFilter(boolean p_85082_, boolean p_85083_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
if (p_85082_) {
|
||||
GlStateManager._texParameter(3553, 10241, p_85083_ ? 9987 : 9729);
|
||||
GlStateManager._texParameter(3553, 10240, 9729);
|
||||
} else {
|
||||
GlStateManager._texParameter(3553, 10241, p_85083_ ? 9986 : 9728);
|
||||
GlStateManager._texParameter(3553, 10240, 9728);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void checkAllocated() {
|
||||
if (this.pixels == 0L) {
|
||||
throw new IllegalStateException("Image is not allocated.");
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (this.pixels != 0L) {
|
||||
if (this.useStbFree) {
|
||||
STBImage.nstbi_image_free(this.pixels);
|
||||
} else {
|
||||
MemoryUtil.nmemFree(this.pixels);
|
||||
}
|
||||
}
|
||||
|
||||
this.pixels = 0L;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return this.width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
public NativeImage.Format format() {
|
||||
return this.format;
|
||||
}
|
||||
|
||||
public int getPixelRGBA(int p_84986_, int p_84987_) {
|
||||
if (this.format != NativeImage.Format.RGBA) {
|
||||
throw new IllegalArgumentException(String.format(Locale.ROOT, "getPixelRGBA only works on RGBA images; have %s", this.format));
|
||||
} else if (this.isOutsideBounds(p_84986_, p_84987_)) {
|
||||
throw new IllegalArgumentException(String.format(Locale.ROOT, "(%s, %s) outside of image bounds (%s, %s)", p_84986_, p_84987_, this.width, this.height));
|
||||
} else {
|
||||
this.checkAllocated();
|
||||
long i = ((long)p_84986_ + (long)p_84987_ * (long)this.width) * 4L;
|
||||
return MemoryUtil.memGetInt(this.pixels + i);
|
||||
}
|
||||
}
|
||||
|
||||
public void setPixelRGBA(int p_84989_, int p_84990_, int p_84991_) {
|
||||
if (this.format != NativeImage.Format.RGBA) {
|
||||
throw new IllegalArgumentException(String.format(Locale.ROOT, "setPixelRGBA only works on RGBA images; have %s", this.format));
|
||||
} else if (this.isOutsideBounds(p_84989_, p_84990_)) {
|
||||
throw new IllegalArgumentException(String.format(Locale.ROOT, "(%s, %s) outside of image bounds (%s, %s)", p_84989_, p_84990_, this.width, this.height));
|
||||
} else {
|
||||
this.checkAllocated();
|
||||
long i = ((long)p_84989_ + (long)p_84990_ * (long)this.width) * 4L;
|
||||
MemoryUtil.memPutInt(this.pixels + i, p_84991_);
|
||||
}
|
||||
}
|
||||
|
||||
public NativeImage mappedCopy(IntUnaryOperator p_267084_) {
|
||||
if (this.format != NativeImage.Format.RGBA) {
|
||||
throw new IllegalArgumentException(String.format(Locale.ROOT, "function application only works on RGBA images; have %s", this.format));
|
||||
} else {
|
||||
this.checkAllocated();
|
||||
NativeImage nativeimage = new NativeImage(this.width, this.height, false);
|
||||
int i = this.width * this.height;
|
||||
IntBuffer intbuffer = MemoryUtil.memIntBuffer(this.pixels, i);
|
||||
IntBuffer intbuffer1 = MemoryUtil.memIntBuffer(nativeimage.pixels, i);
|
||||
|
||||
for(int j = 0; j < i; ++j) {
|
||||
intbuffer1.put(j, p_267084_.applyAsInt(intbuffer.get(j)));
|
||||
}
|
||||
|
||||
return nativeimage;
|
||||
}
|
||||
}
|
||||
|
||||
public void applyToAllPixels(IntUnaryOperator p_285490_) {
|
||||
if (this.format != NativeImage.Format.RGBA) {
|
||||
throw new IllegalArgumentException(String.format(Locale.ROOT, "function application only works on RGBA images; have %s", this.format));
|
||||
} else {
|
||||
this.checkAllocated();
|
||||
int i = this.width * this.height;
|
||||
IntBuffer intbuffer = MemoryUtil.memIntBuffer(this.pixels, i);
|
||||
|
||||
for(int j = 0; j < i; ++j) {
|
||||
intbuffer.put(j, p_285490_.applyAsInt(intbuffer.get(j)));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public int[] getPixelsRGBA() {
|
||||
if (this.format != NativeImage.Format.RGBA) {
|
||||
throw new IllegalArgumentException(String.format(Locale.ROOT, "getPixelsRGBA only works on RGBA images; have %s", this.format));
|
||||
} else {
|
||||
this.checkAllocated();
|
||||
int[] aint = new int[this.width * this.height];
|
||||
MemoryUtil.memIntBuffer(this.pixels, this.width * this.height).get(aint);
|
||||
return aint;
|
||||
}
|
||||
}
|
||||
|
||||
public void setPixelLuminance(int p_166403_, int p_166404_, byte p_166405_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
if (!this.format.hasLuminance()) {
|
||||
throw new IllegalArgumentException(String.format(Locale.ROOT, "setPixelLuminance only works on image with luminance; have %s", this.format));
|
||||
} else if (this.isOutsideBounds(p_166403_, p_166404_)) {
|
||||
throw new IllegalArgumentException(String.format(Locale.ROOT, "(%s, %s) outside of image bounds (%s, %s)", p_166403_, p_166404_, this.width, this.height));
|
||||
} else {
|
||||
this.checkAllocated();
|
||||
long i = ((long)p_166403_ + (long)p_166404_ * (long)this.width) * (long)this.format.components() + (long)(this.format.luminanceOffset() / 8);
|
||||
MemoryUtil.memPutByte(this.pixels + i, p_166405_);
|
||||
}
|
||||
}
|
||||
|
||||
public byte getRedOrLuminance(int p_166409_, int p_166410_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
if (!this.format.hasLuminanceOrRed()) {
|
||||
throw new IllegalArgumentException(String.format(Locale.ROOT, "no red or luminance in %s", this.format));
|
||||
} else if (this.isOutsideBounds(p_166409_, p_166410_)) {
|
||||
throw new IllegalArgumentException(String.format(Locale.ROOT, "(%s, %s) outside of image bounds (%s, %s)", p_166409_, p_166410_, this.width, this.height));
|
||||
} else {
|
||||
int i = (p_166409_ + p_166410_ * this.width) * this.format.components() + this.format.luminanceOrRedOffset() / 8;
|
||||
return MemoryUtil.memGetByte(this.pixels + (long)i);
|
||||
}
|
||||
}
|
||||
|
||||
public byte getGreenOrLuminance(int p_166416_, int p_166417_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
if (!this.format.hasLuminanceOrGreen()) {
|
||||
throw new IllegalArgumentException(String.format(Locale.ROOT, "no green or luminance in %s", this.format));
|
||||
} else if (this.isOutsideBounds(p_166416_, p_166417_)) {
|
||||
throw new IllegalArgumentException(String.format(Locale.ROOT, "(%s, %s) outside of image bounds (%s, %s)", p_166416_, p_166417_, this.width, this.height));
|
||||
} else {
|
||||
int i = (p_166416_ + p_166417_ * this.width) * this.format.components() + this.format.luminanceOrGreenOffset() / 8;
|
||||
return MemoryUtil.memGetByte(this.pixels + (long)i);
|
||||
}
|
||||
}
|
||||
|
||||
public byte getBlueOrLuminance(int p_166419_, int p_166420_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
if (!this.format.hasLuminanceOrBlue()) {
|
||||
throw new IllegalArgumentException(String.format(Locale.ROOT, "no blue or luminance in %s", this.format));
|
||||
} else if (this.isOutsideBounds(p_166419_, p_166420_)) {
|
||||
throw new IllegalArgumentException(String.format(Locale.ROOT, "(%s, %s) outside of image bounds (%s, %s)", p_166419_, p_166420_, this.width, this.height));
|
||||
} else {
|
||||
int i = (p_166419_ + p_166420_ * this.width) * this.format.components() + this.format.luminanceOrBlueOffset() / 8;
|
||||
return MemoryUtil.memGetByte(this.pixels + (long)i);
|
||||
}
|
||||
}
|
||||
|
||||
public byte getLuminanceOrAlpha(int p_85088_, int p_85089_) {
|
||||
if (!this.format.hasLuminanceOrAlpha()) {
|
||||
throw new IllegalArgumentException(String.format(Locale.ROOT, "no luminance or alpha in %s", this.format));
|
||||
} else if (this.isOutsideBounds(p_85088_, p_85089_)) {
|
||||
throw new IllegalArgumentException(String.format(Locale.ROOT, "(%s, %s) outside of image bounds (%s, %s)", p_85088_, p_85089_, this.width, this.height));
|
||||
} else {
|
||||
int i = (p_85088_ + p_85089_ * this.width) * this.format.components() + this.format.luminanceOrAlphaOffset() / 8;
|
||||
return MemoryUtil.memGetByte(this.pixels + (long)i);
|
||||
}
|
||||
}
|
||||
|
||||
public void blendPixel(int p_166412_, int p_166413_, int p_166414_) {
|
||||
if (this.format != NativeImage.Format.RGBA) {
|
||||
throw new UnsupportedOperationException("Can only call blendPixel with RGBA format");
|
||||
} else {
|
||||
int i = this.getPixelRGBA(p_166412_, p_166413_);
|
||||
float f = (float)FastColor.ABGR32.alpha(p_166414_) / 255.0F;
|
||||
float f1 = (float)FastColor.ABGR32.blue(p_166414_) / 255.0F;
|
||||
float f2 = (float)FastColor.ABGR32.green(p_166414_) / 255.0F;
|
||||
float f3 = (float)FastColor.ABGR32.red(p_166414_) / 255.0F;
|
||||
float f4 = (float)FastColor.ABGR32.alpha(i) / 255.0F;
|
||||
float f5 = (float)FastColor.ABGR32.blue(i) / 255.0F;
|
||||
float f6 = (float)FastColor.ABGR32.green(i) / 255.0F;
|
||||
float f7 = (float)FastColor.ABGR32.red(i) / 255.0F;
|
||||
float f8 = 1.0F - f;
|
||||
float f9 = f * f + f4 * f8;
|
||||
float f10 = f1 * f + f5 * f8;
|
||||
float f11 = f2 * f + f6 * f8;
|
||||
float f12 = f3 * f + f7 * f8;
|
||||
if (f9 > 1.0F) {
|
||||
f9 = 1.0F;
|
||||
}
|
||||
|
||||
if (f10 > 1.0F) {
|
||||
f10 = 1.0F;
|
||||
}
|
||||
|
||||
if (f11 > 1.0F) {
|
||||
f11 = 1.0F;
|
||||
}
|
||||
|
||||
if (f12 > 1.0F) {
|
||||
f12 = 1.0F;
|
||||
}
|
||||
|
||||
int j = (int)(f9 * 255.0F);
|
||||
int k = (int)(f10 * 255.0F);
|
||||
int l = (int)(f11 * 255.0F);
|
||||
int i1 = (int)(f12 * 255.0F);
|
||||
this.setPixelRGBA(p_166412_, p_166413_, FastColor.ABGR32.color(j, k, l, i1));
|
||||
}
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
public int[] makePixelArray() {
|
||||
if (this.format != NativeImage.Format.RGBA) {
|
||||
throw new UnsupportedOperationException("can only call makePixelArray for RGBA images.");
|
||||
} else {
|
||||
this.checkAllocated();
|
||||
int[] aint = new int[this.getWidth() * this.getHeight()];
|
||||
|
||||
for(int i = 0; i < this.getHeight(); ++i) {
|
||||
for(int j = 0; j < this.getWidth(); ++j) {
|
||||
int k = this.getPixelRGBA(j, i);
|
||||
aint[j + i * this.getWidth()] = FastColor.ARGB32.color(FastColor.ABGR32.alpha(k), FastColor.ABGR32.red(k), FastColor.ABGR32.green(k), FastColor.ABGR32.blue(k));
|
||||
}
|
||||
}
|
||||
|
||||
return aint;
|
||||
}
|
||||
}
|
||||
|
||||
public void upload(int p_85041_, int p_85042_, int p_85043_, boolean p_85044_) {
|
||||
this.upload(p_85041_, p_85042_, p_85043_, 0, 0, this.width, this.height, false, p_85044_);
|
||||
}
|
||||
|
||||
public void upload(int p_85004_, int p_85005_, int p_85006_, int p_85007_, int p_85008_, int p_85009_, int p_85010_, boolean p_85011_, boolean p_85012_) {
|
||||
this.upload(p_85004_, p_85005_, p_85006_, p_85007_, p_85008_, p_85009_, p_85010_, false, false, p_85011_, p_85012_);
|
||||
}
|
||||
|
||||
public void upload(int p_85014_, int p_85015_, int p_85016_, int p_85017_, int p_85018_, int p_85019_, int p_85020_, boolean p_85021_, boolean p_85022_, boolean p_85023_, boolean p_85024_) {
|
||||
if (!RenderSystem.isOnRenderThreadOrInit()) {
|
||||
RenderSystem.recordRenderCall(() -> {
|
||||
this._upload(p_85014_, p_85015_, p_85016_, p_85017_, p_85018_, p_85019_, p_85020_, p_85021_, p_85022_, p_85023_, p_85024_);
|
||||
});
|
||||
} else {
|
||||
this._upload(p_85014_, p_85015_, p_85016_, p_85017_, p_85018_, p_85019_, p_85020_, p_85021_, p_85022_, p_85023_, p_85024_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void _upload(int p_85091_, int p_85092_, int p_85093_, int p_85094_, int p_85095_, int p_85096_, int p_85097_, boolean p_85098_, boolean p_85099_, boolean p_85100_, boolean p_85101_) {
|
||||
try {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
this.checkAllocated();
|
||||
setFilter(p_85098_, p_85100_);
|
||||
if (p_85096_ == this.getWidth()) {
|
||||
GlStateManager._pixelStore(3314, 0);
|
||||
} else {
|
||||
GlStateManager._pixelStore(3314, this.getWidth());
|
||||
}
|
||||
|
||||
GlStateManager._pixelStore(3316, p_85094_);
|
||||
GlStateManager._pixelStore(3315, p_85095_);
|
||||
this.format.setUnpackPixelStoreState();
|
||||
GlStateManager._texSubImage2D(3553, p_85091_, p_85092_, p_85093_, p_85096_, p_85097_, this.format.glFormat(), 5121, this.pixels);
|
||||
if (p_85099_) {
|
||||
GlStateManager._texParameter(3553, 10242, 33071);
|
||||
GlStateManager._texParameter(3553, 10243, 33071);
|
||||
}
|
||||
} finally {
|
||||
if (p_85101_) {
|
||||
this.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void downloadTexture(int p_85046_, boolean p_85047_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
this.checkAllocated();
|
||||
this.format.setPackPixelStoreState();
|
||||
GlStateManager._getTexImage(3553, p_85046_, this.format.glFormat(), 5121, this.pixels);
|
||||
if (p_85047_ && this.format.hasAlpha()) {
|
||||
for(int i = 0; i < this.getHeight(); ++i) {
|
||||
for(int j = 0; j < this.getWidth(); ++j) {
|
||||
this.setPixelRGBA(j, i, this.getPixelRGBA(j, i) | 255 << this.format.alphaOffset());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void downloadDepthBuffer(float p_166401_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
if (this.format.components() != 1) {
|
||||
throw new IllegalStateException("Depth buffer must be stored in NativeImage with 1 component.");
|
||||
} else {
|
||||
this.checkAllocated();
|
||||
this.format.setPackPixelStoreState();
|
||||
GlStateManager._readPixels(0, 0, this.width, this.height, 6402, 5121, this.pixels);
|
||||
}
|
||||
}
|
||||
|
||||
public void drawPixels() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
this.format.setUnpackPixelStoreState();
|
||||
GlStateManager._glDrawPixels(this.width, this.height, this.format.glFormat(), 5121, this.pixels);
|
||||
}
|
||||
|
||||
public void writeToFile(File p_85057_) throws IOException {
|
||||
this.writeToFile(p_85057_.toPath());
|
||||
}
|
||||
|
||||
public void copyFromFont(STBTTFontinfo p_85069_, int p_85070_, int p_85071_, int p_85072_, float p_85073_, float p_85074_, float p_85075_, float p_85076_, int p_85077_, int p_85078_) {
|
||||
if (p_85077_ >= 0 && p_85077_ + p_85071_ <= this.getWidth() && p_85078_ >= 0 && p_85078_ + p_85072_ <= this.getHeight()) {
|
||||
if (this.format.components() != 1) {
|
||||
throw new IllegalArgumentException("Can only write fonts into 1-component images.");
|
||||
} else {
|
||||
STBTruetype.nstbtt_MakeGlyphBitmapSubpixel(p_85069_.address(), this.pixels + (long)p_85077_ + (long)(p_85078_ * this.getWidth()), p_85071_, p_85072_, this.getWidth(), p_85073_, p_85074_, p_85075_, p_85076_, p_85070_);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException(String.format(Locale.ROOT, "Out of bounds: start: (%s, %s) (size: %sx%s); size: %sx%s", p_85077_, p_85078_, p_85071_, p_85072_, this.getWidth(), this.getHeight()));
|
||||
}
|
||||
}
|
||||
|
||||
public void writeToFile(Path p_85067_) throws IOException {
|
||||
if (!this.format.supportedByStb()) {
|
||||
throw new UnsupportedOperationException("Don't know how to write format " + this.format);
|
||||
} else {
|
||||
this.checkAllocated();
|
||||
|
||||
try (WritableByteChannel writablebytechannel = Files.newByteChannel(p_85067_, OPEN_OPTIONS)) {
|
||||
if (!this.writeToChannel(writablebytechannel)) {
|
||||
throw new IOException("Could not write image to the PNG file \"" + p_85067_.toAbsolutePath() + "\": " + STBImage.stbi_failure_reason());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] asByteArray() throws IOException {
|
||||
try (
|
||||
ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
|
||||
WritableByteChannel writablebytechannel = Channels.newChannel(bytearrayoutputstream);
|
||||
) {
|
||||
if (!this.writeToChannel(writablebytechannel)) {
|
||||
throw new IOException("Could not write image to byte array: " + STBImage.stbi_failure_reason());
|
||||
} else {
|
||||
return bytearrayoutputstream.toByteArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean writeToChannel(WritableByteChannel p_85065_) throws IOException {
|
||||
NativeImage.WriteCallback nativeimage$writecallback = new NativeImage.WriteCallback(p_85065_);
|
||||
|
||||
boolean flag;
|
||||
try {
|
||||
int i = Math.min(this.getHeight(), Integer.MAX_VALUE / this.getWidth() / this.format.components());
|
||||
if (i < this.getHeight()) {
|
||||
LOGGER.warn("Dropping image height from {} to {} to fit the size into 32-bit signed int", this.getHeight(), i);
|
||||
}
|
||||
|
||||
if (STBImageWrite.nstbi_write_png_to_func(nativeimage$writecallback.address(), 0L, this.getWidth(), i, this.format.components(), this.pixels, 0) != 0) {
|
||||
nativeimage$writecallback.throwIfException();
|
||||
return true;
|
||||
}
|
||||
|
||||
flag = false;
|
||||
} finally {
|
||||
nativeimage$writecallback.free();
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
public void copyFrom(NativeImage p_85055_) {
|
||||
if (p_85055_.format() != this.format) {
|
||||
throw new UnsupportedOperationException("Image formats don't match.");
|
||||
} else {
|
||||
int i = this.format.components();
|
||||
this.checkAllocated();
|
||||
p_85055_.checkAllocated();
|
||||
if (this.width == p_85055_.width) {
|
||||
MemoryUtil.memCopy(p_85055_.pixels, this.pixels, Math.min(this.size, p_85055_.size));
|
||||
} else {
|
||||
int j = Math.min(this.getWidth(), p_85055_.getWidth());
|
||||
int k = Math.min(this.getHeight(), p_85055_.getHeight());
|
||||
|
||||
for(int l = 0; l < k; ++l) {
|
||||
int i1 = l * p_85055_.getWidth() * i;
|
||||
int j1 = l * this.getWidth() * i;
|
||||
MemoryUtil.memCopy(p_85055_.pixels + (long)i1, this.pixels + (long)j1, (long)j);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void fillRect(int p_84998_, int p_84999_, int p_85000_, int p_85001_, int p_85002_) {
|
||||
for(int i = p_84999_; i < p_84999_ + p_85001_; ++i) {
|
||||
for(int j = p_84998_; j < p_84998_ + p_85000_; ++j) {
|
||||
this.setPixelRGBA(j, i, p_85002_);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void copyRect(int p_85026_, int p_85027_, int p_85028_, int p_85029_, int p_85030_, int p_85031_, boolean p_85032_, boolean p_85033_) {
|
||||
this.copyRect(this, p_85026_, p_85027_, p_85026_ + p_85028_, p_85027_ + p_85029_, p_85030_, p_85031_, p_85032_, p_85033_);
|
||||
}
|
||||
|
||||
public void copyRect(NativeImage p_261644_, int p_262056_, int p_261490_, int p_261959_, int p_262110_, int p_261522_, int p_261505_, boolean p_261480_, boolean p_261622_) {
|
||||
for(int i = 0; i < p_261505_; ++i) {
|
||||
for(int j = 0; j < p_261522_; ++j) {
|
||||
int k = p_261480_ ? p_261522_ - 1 - j : j;
|
||||
int l = p_261622_ ? p_261505_ - 1 - i : i;
|
||||
int i1 = this.getPixelRGBA(p_262056_ + j, p_261490_ + i);
|
||||
p_261644_.setPixelRGBA(p_261959_ + k, p_262110_ + l, i1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void flipY() {
|
||||
this.checkAllocated();
|
||||
|
||||
try (MemoryStack memorystack = MemoryStack.stackPush()) {
|
||||
int i = this.format.components();
|
||||
int j = this.getWidth() * i;
|
||||
long k = memorystack.nmalloc(j);
|
||||
|
||||
for(int l = 0; l < this.getHeight() / 2; ++l) {
|
||||
int i1 = l * this.getWidth() * i;
|
||||
int j1 = (this.getHeight() - 1 - l) * this.getWidth() * i;
|
||||
MemoryUtil.memCopy(this.pixels + (long)i1, k, (long)j);
|
||||
MemoryUtil.memCopy(this.pixels + (long)j1, this.pixels + (long)i1, (long)j);
|
||||
MemoryUtil.memCopy(k, this.pixels + (long)j1, (long)j);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void resizeSubRectTo(int p_85035_, int p_85036_, int p_85037_, int p_85038_, NativeImage p_85039_) {
|
||||
this.checkAllocated();
|
||||
if (p_85039_.format() != this.format) {
|
||||
throw new UnsupportedOperationException("resizeSubRectTo only works for images of the same format.");
|
||||
} else {
|
||||
int i = this.format.components();
|
||||
STBImageResize.nstbir_resize_uint8(this.pixels + (long)((p_85035_ + p_85036_ * this.getWidth()) * i), p_85037_, p_85038_, this.getWidth() * i, p_85039_.pixels, p_85039_.getWidth(), p_85039_.getHeight(), 0, i);
|
||||
}
|
||||
}
|
||||
|
||||
public void untrack() {
|
||||
DebugMemoryUntracker.untrack(this.pixels);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum Format {
|
||||
RGBA(4, 6408, true, true, true, false, true, 0, 8, 16, 255, 24, true),
|
||||
RGB(3, 6407, true, true, true, false, false, 0, 8, 16, 255, 255, true),
|
||||
LUMINANCE_ALPHA(2, 33319, false, false, false, true, true, 255, 255, 255, 0, 8, true),
|
||||
LUMINANCE(1, 6403, false, false, false, true, false, 0, 0, 0, 0, 255, true);
|
||||
|
||||
final int components;
|
||||
private final int glFormat;
|
||||
private final boolean hasRed;
|
||||
private final boolean hasGreen;
|
||||
private final boolean hasBlue;
|
||||
private final boolean hasLuminance;
|
||||
private final boolean hasAlpha;
|
||||
private final int redOffset;
|
||||
private final int greenOffset;
|
||||
private final int blueOffset;
|
||||
private final int luminanceOffset;
|
||||
private final int alphaOffset;
|
||||
private final boolean supportedByStb;
|
||||
|
||||
private Format(int p_85148_, int p_85149_, boolean p_85150_, boolean p_85151_, boolean p_85152_, boolean p_85153_, boolean p_85154_, int p_85155_, int p_85156_, int p_85157_, int p_85158_, int p_85159_, boolean p_85160_) {
|
||||
this.components = p_85148_;
|
||||
this.glFormat = p_85149_;
|
||||
this.hasRed = p_85150_;
|
||||
this.hasGreen = p_85151_;
|
||||
this.hasBlue = p_85152_;
|
||||
this.hasLuminance = p_85153_;
|
||||
this.hasAlpha = p_85154_;
|
||||
this.redOffset = p_85155_;
|
||||
this.greenOffset = p_85156_;
|
||||
this.blueOffset = p_85157_;
|
||||
this.luminanceOffset = p_85158_;
|
||||
this.alphaOffset = p_85159_;
|
||||
this.supportedByStb = p_85160_;
|
||||
}
|
||||
|
||||
public int components() {
|
||||
return this.components;
|
||||
}
|
||||
|
||||
public void setPackPixelStoreState() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GlStateManager._pixelStore(3333, this.components());
|
||||
}
|
||||
|
||||
public void setUnpackPixelStoreState() {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GlStateManager._pixelStore(3317, this.components());
|
||||
}
|
||||
|
||||
public int glFormat() {
|
||||
return this.glFormat;
|
||||
}
|
||||
|
||||
public boolean hasRed() {
|
||||
return this.hasRed;
|
||||
}
|
||||
|
||||
public boolean hasGreen() {
|
||||
return this.hasGreen;
|
||||
}
|
||||
|
||||
public boolean hasBlue() {
|
||||
return this.hasBlue;
|
||||
}
|
||||
|
||||
public boolean hasLuminance() {
|
||||
return this.hasLuminance;
|
||||
}
|
||||
|
||||
public boolean hasAlpha() {
|
||||
return this.hasAlpha;
|
||||
}
|
||||
|
||||
public int redOffset() {
|
||||
return this.redOffset;
|
||||
}
|
||||
|
||||
public int greenOffset() {
|
||||
return this.greenOffset;
|
||||
}
|
||||
|
||||
public int blueOffset() {
|
||||
return this.blueOffset;
|
||||
}
|
||||
|
||||
public int luminanceOffset() {
|
||||
return this.luminanceOffset;
|
||||
}
|
||||
|
||||
public int alphaOffset() {
|
||||
return this.alphaOffset;
|
||||
}
|
||||
|
||||
public boolean hasLuminanceOrRed() {
|
||||
return this.hasLuminance || this.hasRed;
|
||||
}
|
||||
|
||||
public boolean hasLuminanceOrGreen() {
|
||||
return this.hasLuminance || this.hasGreen;
|
||||
}
|
||||
|
||||
public boolean hasLuminanceOrBlue() {
|
||||
return this.hasLuminance || this.hasBlue;
|
||||
}
|
||||
|
||||
public boolean hasLuminanceOrAlpha() {
|
||||
return this.hasLuminance || this.hasAlpha;
|
||||
}
|
||||
|
||||
public int luminanceOrRedOffset() {
|
||||
return this.hasLuminance ? this.luminanceOffset : this.redOffset;
|
||||
}
|
||||
|
||||
public int luminanceOrGreenOffset() {
|
||||
return this.hasLuminance ? this.luminanceOffset : this.greenOffset;
|
||||
}
|
||||
|
||||
public int luminanceOrBlueOffset() {
|
||||
return this.hasLuminance ? this.luminanceOffset : this.blueOffset;
|
||||
}
|
||||
|
||||
public int luminanceOrAlphaOffset() {
|
||||
return this.hasLuminance ? this.luminanceOffset : this.alphaOffset;
|
||||
}
|
||||
|
||||
public boolean supportedByStb() {
|
||||
return this.supportedByStb;
|
||||
}
|
||||
|
||||
static NativeImage.Format getStbFormat(int p_85168_) {
|
||||
switch (p_85168_) {
|
||||
case 1:
|
||||
return LUMINANCE;
|
||||
case 2:
|
||||
return LUMINANCE_ALPHA;
|
||||
case 3:
|
||||
return RGB;
|
||||
case 4:
|
||||
default:
|
||||
return RGBA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum InternalGlFormat {
|
||||
RGBA(6408),
|
||||
RGB(6407),
|
||||
RG(33319),
|
||||
RED(6403);
|
||||
|
||||
private final int glFormat;
|
||||
|
||||
private InternalGlFormat(int p_85190_) {
|
||||
this.glFormat = p_85190_;
|
||||
}
|
||||
|
||||
public int glFormat() {
|
||||
return this.glFormat;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class WriteCallback extends STBIWriteCallback {
|
||||
private final WritableByteChannel output;
|
||||
@Nullable
|
||||
private IOException exception;
|
||||
|
||||
WriteCallback(WritableByteChannel p_85198_) {
|
||||
this.output = p_85198_;
|
||||
}
|
||||
|
||||
public void invoke(long p_85204_, long p_85205_, int p_85206_) {
|
||||
ByteBuffer bytebuffer = getData(p_85205_, p_85206_);
|
||||
|
||||
try {
|
||||
this.output.write(bytebuffer);
|
||||
} catch (IOException ioexception) {
|
||||
this.exception = ioexception;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void throwIfException() throws IOException {
|
||||
if (this.exception != null) {
|
||||
throw this.exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package com.mojang.blaze3d.platform;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.glfw.GLFWMonitorCallback;
|
||||
import org.lwjgl.glfw.GLFWMonitorCallbackI;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class ScreenManager {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final Long2ObjectMap<Monitor> monitors = new Long2ObjectOpenHashMap<>();
|
||||
private final MonitorCreator monitorCreator;
|
||||
|
||||
public ScreenManager(MonitorCreator p_85265_) {
|
||||
RenderSystem.assertInInitPhase();
|
||||
this.monitorCreator = p_85265_;
|
||||
GLFW.glfwSetMonitorCallback(this::onMonitorChange);
|
||||
PointerBuffer pointerbuffer = GLFW.glfwGetMonitors();
|
||||
if (pointerbuffer != null) {
|
||||
for(int i = 0; i < pointerbuffer.limit(); ++i) {
|
||||
long j = pointerbuffer.get(i);
|
||||
this.monitors.put(j, p_85265_.createMonitor(j));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void onMonitorChange(long p_85274_, int p_85275_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
if (p_85275_ == 262145) {
|
||||
this.monitors.put(p_85274_, this.monitorCreator.createMonitor(p_85274_));
|
||||
LOGGER.debug("Monitor {} connected. Current monitors: {}", p_85274_, this.monitors);
|
||||
} else if (p_85275_ == 262146) {
|
||||
this.monitors.remove(p_85274_);
|
||||
LOGGER.debug("Monitor {} disconnected. Current monitors: {}", p_85274_, this.monitors);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Monitor getMonitor(long p_85272_) {
|
||||
RenderSystem.assertInInitPhase();
|
||||
return this.monitors.get(p_85272_);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Monitor findBestMonitor(Window p_85277_) {
|
||||
long i = GLFW.glfwGetWindowMonitor(p_85277_.getWindow());
|
||||
if (i != 0L) {
|
||||
return this.getMonitor(i);
|
||||
} else {
|
||||
int j = p_85277_.getX();
|
||||
int k = j + p_85277_.getScreenWidth();
|
||||
int l = p_85277_.getY();
|
||||
int i1 = l + p_85277_.getScreenHeight();
|
||||
int j1 = -1;
|
||||
Monitor monitor = null;
|
||||
long k1 = GLFW.glfwGetPrimaryMonitor();
|
||||
LOGGER.debug("Selecting monitor - primary: {}, current monitors: {}", k1, this.monitors);
|
||||
|
||||
for(Monitor monitor1 : this.monitors.values()) {
|
||||
int l1 = monitor1.getX();
|
||||
int i2 = l1 + monitor1.getCurrentMode().getWidth();
|
||||
int j2 = monitor1.getY();
|
||||
int k2 = j2 + monitor1.getCurrentMode().getHeight();
|
||||
int l2 = clamp(j, l1, i2);
|
||||
int i3 = clamp(k, l1, i2);
|
||||
int j3 = clamp(l, j2, k2);
|
||||
int k3 = clamp(i1, j2, k2);
|
||||
int l3 = Math.max(0, i3 - l2);
|
||||
int i4 = Math.max(0, k3 - j3);
|
||||
int j4 = l3 * i4;
|
||||
if (j4 > j1) {
|
||||
monitor = monitor1;
|
||||
j1 = j4;
|
||||
} else if (j4 == j1 && k1 == monitor1.getMonitor()) {
|
||||
LOGGER.debug("Primary monitor {} is preferred to monitor {}", monitor1, monitor);
|
||||
monitor = monitor1;
|
||||
}
|
||||
}
|
||||
|
||||
LOGGER.debug("Selected monitor: {}", (Object)monitor);
|
||||
return monitor;
|
||||
}
|
||||
}
|
||||
|
||||
public static int clamp(int p_85268_, int p_85269_, int p_85270_) {
|
||||
if (p_85268_ < p_85269_) {
|
||||
return p_85269_;
|
||||
} else {
|
||||
return p_85268_ > p_85270_ ? p_85270_ : p_85268_;
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GLFWMonitorCallback glfwmonitorcallback = GLFW.glfwSetMonitorCallback((GLFWMonitorCallbackI)null);
|
||||
if (glfwmonitorcallback != null) {
|
||||
glfwmonitorcallback.free();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
package com.mojang.blaze3d.platform;
|
||||
|
||||
import com.mojang.blaze3d.DontObfuscate;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.SeekableByteChannel;
|
||||
import java.nio.file.Path;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.function.IntUnaryOperator;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@DontObfuscate
|
||||
public class TextureUtil {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
public static final int MIN_MIPMAP_LEVEL = 0;
|
||||
private static final int DEFAULT_IMAGE_BUFFER_SIZE = 8192;
|
||||
|
||||
public static int generateTextureId() {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
if (SharedConstants.IS_RUNNING_IN_IDE) {
|
||||
int[] aint = new int[ThreadLocalRandom.current().nextInt(15) + 1];
|
||||
GlStateManager._genTextures(aint);
|
||||
int i = GlStateManager._genTexture();
|
||||
GlStateManager._deleteTextures(aint);
|
||||
return i;
|
||||
} else {
|
||||
return GlStateManager._genTexture();
|
||||
}
|
||||
}
|
||||
|
||||
public static void releaseTextureId(int p_85282_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GlStateManager._deleteTexture(p_85282_);
|
||||
}
|
||||
|
||||
public static void prepareImage(int p_85284_, int p_85285_, int p_85286_) {
|
||||
prepareImage(NativeImage.InternalGlFormat.RGBA, p_85284_, 0, p_85285_, p_85286_);
|
||||
}
|
||||
|
||||
public static void prepareImage(NativeImage.InternalGlFormat p_85293_, int p_85294_, int p_85295_, int p_85296_) {
|
||||
prepareImage(p_85293_, p_85294_, 0, p_85295_, p_85296_);
|
||||
}
|
||||
|
||||
public static void prepareImage(int p_85288_, int p_85289_, int p_85290_, int p_85291_) {
|
||||
prepareImage(NativeImage.InternalGlFormat.RGBA, p_85288_, p_85289_, p_85290_, p_85291_);
|
||||
}
|
||||
|
||||
public static void prepareImage(NativeImage.InternalGlFormat p_85298_, int p_85299_, int p_85300_, int p_85301_, int p_85302_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
bind(p_85299_);
|
||||
if (p_85300_ >= 0) {
|
||||
GlStateManager._texParameter(3553, 33085, p_85300_);
|
||||
GlStateManager._texParameter(3553, 33082, 0);
|
||||
GlStateManager._texParameter(3553, 33083, p_85300_);
|
||||
GlStateManager._texParameter(3553, 34049, 0.0F);
|
||||
}
|
||||
|
||||
for(int i = 0; i <= p_85300_; ++i) {
|
||||
GlStateManager._texImage2D(3553, i, p_85298_.glFormat(), p_85301_ >> i, p_85302_ >> i, 0, 6408, 5121, (IntBuffer)null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void bind(int p_85310_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
GlStateManager._bindTexture(p_85310_);
|
||||
}
|
||||
|
||||
public static ByteBuffer readResource(InputStream p_85304_) throws IOException {
|
||||
ReadableByteChannel readablebytechannel = Channels.newChannel(p_85304_);
|
||||
if (readablebytechannel instanceof SeekableByteChannel seekablebytechannel) {
|
||||
return readResource(readablebytechannel, (int)seekablebytechannel.size() + 1);
|
||||
} else {
|
||||
return readResource(readablebytechannel, 8192);
|
||||
}
|
||||
}
|
||||
|
||||
private static ByteBuffer readResource(ReadableByteChannel p_273208_, int p_273297_) throws IOException {
|
||||
ByteBuffer bytebuffer = MemoryUtil.memAlloc(p_273297_);
|
||||
|
||||
try {
|
||||
while(p_273208_.read(bytebuffer) != -1) {
|
||||
if (!bytebuffer.hasRemaining()) {
|
||||
bytebuffer = MemoryUtil.memRealloc(bytebuffer, bytebuffer.capacity() * 2);
|
||||
}
|
||||
}
|
||||
|
||||
return bytebuffer;
|
||||
} catch (IOException ioexception) {
|
||||
MemoryUtil.memFree(bytebuffer);
|
||||
throw ioexception;
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeAsPNG(Path p_261923_, String p_262070_, int p_261655_, int p_261576_, int p_261966_, int p_261775_) {
|
||||
writeAsPNG(p_261923_, p_262070_, p_261655_, p_261576_, p_261966_, p_261775_, (IntUnaryOperator)null);
|
||||
}
|
||||
|
||||
public static void writeAsPNG(Path p_285286_, String p_285408_, int p_285400_, int p_285244_, int p_285373_, int p_285206_, @Nullable IntUnaryOperator p_284988_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
bind(p_285400_);
|
||||
|
||||
for(int i = 0; i <= p_285244_; ++i) {
|
||||
int j = p_285373_ >> i;
|
||||
int k = p_285206_ >> i;
|
||||
|
||||
try (NativeImage nativeimage = new NativeImage(j, k, false)) {
|
||||
nativeimage.downloadTexture(i, false);
|
||||
if (p_284988_ != null) {
|
||||
nativeimage.applyToAllPixels(p_284988_);
|
||||
}
|
||||
|
||||
Path path = p_285286_.resolve(p_285408_ + "_" + i + ".png");
|
||||
nativeimage.writeToFile(path);
|
||||
LOGGER.debug("Exported png to: {}", (Object)path.toAbsolutePath());
|
||||
} catch (IOException ioexception) {
|
||||
LOGGER.debug("Unable to write: ", (Throwable)ioexception);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Path getDebugTexturePath(Path p_262015_) {
|
||||
return p_262015_.resolve("screenshots").resolve("debug");
|
||||
}
|
||||
|
||||
public static Path getDebugTexturePath() {
|
||||
return getDebugTexturePath(Path.of("."));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package com.mojang.blaze3d.platform;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.glfw.GLFWVidMode;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public final class VideoMode {
|
||||
private final int width;
|
||||
private final int height;
|
||||
private final int redBits;
|
||||
private final int greenBits;
|
||||
private final int blueBits;
|
||||
private final int refreshRate;
|
||||
private static final Pattern PATTERN = Pattern.compile("(\\d+)x(\\d+)(?:@(\\d+)(?::(\\d+))?)?");
|
||||
|
||||
public VideoMode(int p_85322_, int p_85323_, int p_85324_, int p_85325_, int p_85326_, int p_85327_) {
|
||||
this.width = p_85322_;
|
||||
this.height = p_85323_;
|
||||
this.redBits = p_85324_;
|
||||
this.greenBits = p_85325_;
|
||||
this.blueBits = p_85326_;
|
||||
this.refreshRate = p_85327_;
|
||||
}
|
||||
|
||||
public VideoMode(GLFWVidMode.Buffer p_85329_) {
|
||||
this.width = p_85329_.width();
|
||||
this.height = p_85329_.height();
|
||||
this.redBits = p_85329_.redBits();
|
||||
this.greenBits = p_85329_.greenBits();
|
||||
this.blueBits = p_85329_.blueBits();
|
||||
this.refreshRate = p_85329_.refreshRate();
|
||||
}
|
||||
|
||||
public VideoMode(GLFWVidMode p_85331_) {
|
||||
this.width = p_85331_.width();
|
||||
this.height = p_85331_.height();
|
||||
this.redBits = p_85331_.redBits();
|
||||
this.greenBits = p_85331_.greenBits();
|
||||
this.blueBits = p_85331_.blueBits();
|
||||
this.refreshRate = p_85331_.refreshRate();
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return this.width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
public int getRedBits() {
|
||||
return this.redBits;
|
||||
}
|
||||
|
||||
public int getGreenBits() {
|
||||
return this.greenBits;
|
||||
}
|
||||
|
||||
public int getBlueBits() {
|
||||
return this.blueBits;
|
||||
}
|
||||
|
||||
public int getRefreshRate() {
|
||||
return this.refreshRate;
|
||||
}
|
||||
|
||||
public boolean equals(Object p_85340_) {
|
||||
if (this == p_85340_) {
|
||||
return true;
|
||||
} else if (p_85340_ != null && this.getClass() == p_85340_.getClass()) {
|
||||
VideoMode videomode = (VideoMode)p_85340_;
|
||||
return this.width == videomode.width && this.height == videomode.height && this.redBits == videomode.redBits && this.greenBits == videomode.greenBits && this.blueBits == videomode.blueBits && this.refreshRate == videomode.refreshRate;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.width, this.height, this.redBits, this.greenBits, this.blueBits, this.refreshRate);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return String.format(Locale.ROOT, "%sx%s@%s (%sbit)", this.width, this.height, this.refreshRate, this.redBits + this.greenBits + this.blueBits);
|
||||
}
|
||||
|
||||
public static Optional<VideoMode> read(@Nullable String p_85334_) {
|
||||
if (p_85334_ == null) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
try {
|
||||
Matcher matcher = PATTERN.matcher(p_85334_);
|
||||
if (matcher.matches()) {
|
||||
int i = Integer.parseInt(matcher.group(1));
|
||||
int j = Integer.parseInt(matcher.group(2));
|
||||
String s = matcher.group(3);
|
||||
int k;
|
||||
if (s == null) {
|
||||
k = 60;
|
||||
} else {
|
||||
k = Integer.parseInt(s);
|
||||
}
|
||||
|
||||
String s1 = matcher.group(4);
|
||||
int l;
|
||||
if (s1 == null) {
|
||||
l = 24;
|
||||
} else {
|
||||
l = Integer.parseInt(s1);
|
||||
}
|
||||
|
||||
int i1 = l / 3;
|
||||
return Optional.of(new VideoMode(i, j, i1, i1, i1, k));
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public String write() {
|
||||
return String.format(Locale.ROOT, "%sx%s@%s:%s", this.width, this.height, this.refreshRate, this.redBits + this.greenBits + this.blueBits);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,457 @@
|
||||
package com.mojang.blaze3d.platform;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
import java.util.Locale.Category;
|
||||
import java.util.function.BiConsumer;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.main.SilentInitException;
|
||||
import net.minecraft.server.packs.PackResources;
|
||||
import net.minecraft.server.packs.resources.IoSupplier;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.glfw.Callbacks;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.glfw.GLFWErrorCallback;
|
||||
import org.lwjgl.glfw.GLFWImage;
|
||||
import org.lwjgl.opengl.GL;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.util.tinyfd.TinyFileDialogs;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public final class Window implements AutoCloseable {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final GLFWErrorCallback defaultErrorCallback = GLFWErrorCallback.create(this::defaultErrorCallback);
|
||||
private final WindowEventHandler eventHandler;
|
||||
private final ScreenManager screenManager;
|
||||
private final long window;
|
||||
private int windowedX;
|
||||
private int windowedY;
|
||||
private int windowedWidth;
|
||||
private int windowedHeight;
|
||||
private Optional<VideoMode> preferredFullscreenVideoMode;
|
||||
private boolean fullscreen;
|
||||
private boolean actuallyFullscreen;
|
||||
private int x;
|
||||
private int y;
|
||||
private int width;
|
||||
private int height;
|
||||
private int framebufferWidth;
|
||||
private int framebufferHeight;
|
||||
private int guiScaledWidth;
|
||||
private int guiScaledHeight;
|
||||
private double guiScale;
|
||||
private String errorSection = "";
|
||||
private boolean dirty;
|
||||
private int framerateLimit;
|
||||
private boolean vsync;
|
||||
|
||||
public Window(WindowEventHandler p_85372_, ScreenManager p_85373_, DisplayData p_85374_, @Nullable String p_85375_, String p_85376_) {
|
||||
RenderSystem.assertInInitPhase();
|
||||
this.screenManager = p_85373_;
|
||||
this.setBootErrorCallback();
|
||||
this.setErrorSection("Pre startup");
|
||||
this.eventHandler = p_85372_;
|
||||
Optional<VideoMode> optional = VideoMode.read(p_85375_);
|
||||
if (optional.isPresent()) {
|
||||
this.preferredFullscreenVideoMode = optional;
|
||||
} else if (p_85374_.fullscreenWidth.isPresent() && p_85374_.fullscreenHeight.isPresent()) {
|
||||
this.preferredFullscreenVideoMode = Optional.of(new VideoMode(p_85374_.fullscreenWidth.getAsInt(), p_85374_.fullscreenHeight.getAsInt(), 8, 8, 8, 60));
|
||||
} else {
|
||||
this.preferredFullscreenVideoMode = Optional.empty();
|
||||
}
|
||||
|
||||
this.actuallyFullscreen = this.fullscreen = p_85374_.isFullscreen;
|
||||
Monitor monitor = p_85373_.getMonitor(GLFW.glfwGetPrimaryMonitor());
|
||||
this.windowedWidth = this.width = p_85374_.width > 0 ? p_85374_.width : 1;
|
||||
this.windowedHeight = this.height = p_85374_.height > 0 ? p_85374_.height : 1;
|
||||
GLFW.glfwDefaultWindowHints();
|
||||
GLFW.glfwWindowHint(139265, 196609);
|
||||
GLFW.glfwWindowHint(139275, 221185);
|
||||
GLFW.glfwWindowHint(139266, 3);
|
||||
GLFW.glfwWindowHint(139267, 2);
|
||||
GLFW.glfwWindowHint(139272, 204801);
|
||||
GLFW.glfwWindowHint(139270, 1);
|
||||
this.window = net.minecraftforge.fml.loading.ImmediateWindowHandler.setupMinecraftWindow(()->this.width, ()->this.height, ()->p_85376_, ()->this.fullscreen && monitor != null ? monitor.getMonitor() : 0L);
|
||||
if (!net.minecraftforge.fml.loading.ImmediateWindowHandler.positionWindow(Optional.ofNullable(monitor), w->this.width = this.windowedWidth = w, h->this.height = this.windowedHeight = h, x->this.x = this.windowedX = x, y->this.y = this.windowedY = y)) {
|
||||
if (monitor != null) {
|
||||
VideoMode videomode = monitor.getPreferredVidMode(this.fullscreen ? this.preferredFullscreenVideoMode : Optional.empty());
|
||||
this.windowedX = this.x = monitor.getX() + videomode.getWidth() / 2 - this.width / 2;
|
||||
this.windowedY = this.y = monitor.getY() + videomode.getHeight() / 2 - this.height / 2;
|
||||
} else {
|
||||
int[] aint1 = new int[1];
|
||||
int[] aint = new int[1];
|
||||
GLFW.glfwGetWindowPos(this.window, aint1, aint);
|
||||
this.windowedX = this.x = aint1[0];
|
||||
this.windowedY = this.y = aint[0];
|
||||
}
|
||||
}
|
||||
|
||||
GLFW.glfwMakeContextCurrent(this.window);
|
||||
Locale locale = Locale.getDefault(Category.FORMAT);
|
||||
Locale.setDefault(Category.FORMAT, Locale.ROOT);
|
||||
GL.createCapabilities();
|
||||
Locale.setDefault(Category.FORMAT, locale);
|
||||
this.setMode();
|
||||
this.refreshFramebufferSize();
|
||||
GLFW.glfwSetFramebufferSizeCallback(this.window, this::onFramebufferResize);
|
||||
GLFW.glfwSetWindowPosCallback(this.window, this::onMove);
|
||||
GLFW.glfwSetWindowSizeCallback(this.window, this::onResize);
|
||||
GLFW.glfwSetWindowFocusCallback(this.window, this::onFocus);
|
||||
GLFW.glfwSetCursorEnterCallback(this.window, this::onEnter);
|
||||
}
|
||||
|
||||
public int getRefreshRate() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
return GLX._getRefreshRate(this);
|
||||
}
|
||||
|
||||
public boolean shouldClose() {
|
||||
return GLX._shouldClose(this);
|
||||
}
|
||||
|
||||
public static void checkGlfwError(BiConsumer<Integer, String> p_85408_) {
|
||||
RenderSystem.assertInInitPhase();
|
||||
|
||||
try (MemoryStack memorystack = MemoryStack.stackPush()) {
|
||||
PointerBuffer pointerbuffer = memorystack.mallocPointer(1);
|
||||
int i = GLFW.glfwGetError(pointerbuffer);
|
||||
if (i != 0) {
|
||||
long j = pointerbuffer.get();
|
||||
String s = j == 0L ? "" : MemoryUtil.memUTF8(j);
|
||||
p_85408_.accept(i, s);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setIcon(PackResources p_281860_, IconSet p_282155_) throws IOException {
|
||||
RenderSystem.assertInInitPhase();
|
||||
if (Minecraft.ON_OSX) {
|
||||
MacosUtil.loadIcon(p_282155_.getMacIcon(p_281860_));
|
||||
} else {
|
||||
List<IoSupplier<InputStream>> list = p_282155_.getStandardIcons(p_281860_);
|
||||
List<ByteBuffer> list1 = new ArrayList<>(list.size());
|
||||
|
||||
try (MemoryStack memorystack = MemoryStack.stackPush()) {
|
||||
GLFWImage.Buffer buffer = GLFWImage.malloc(list.size(), memorystack);
|
||||
|
||||
for(int i = 0; i < list.size(); ++i) {
|
||||
try (NativeImage nativeimage = NativeImage.read(list.get(i).get())) {
|
||||
ByteBuffer bytebuffer = MemoryUtil.memAlloc(nativeimage.getWidth() * nativeimage.getHeight() * 4);
|
||||
list1.add(bytebuffer);
|
||||
bytebuffer.asIntBuffer().put(nativeimage.getPixelsRGBA());
|
||||
buffer.position(i);
|
||||
buffer.width(nativeimage.getWidth());
|
||||
buffer.height(nativeimage.getHeight());
|
||||
buffer.pixels(bytebuffer);
|
||||
}
|
||||
}
|
||||
|
||||
GLFW.glfwSetWindowIcon(this.window, buffer.position(0));
|
||||
} finally {
|
||||
list1.forEach(MemoryUtil::memFree);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void setErrorSection(String p_85404_) {
|
||||
this.errorSection = p_85404_;
|
||||
}
|
||||
|
||||
private void setBootErrorCallback() {
|
||||
RenderSystem.assertInInitPhase();
|
||||
GLFW.glfwSetErrorCallback(Window::bootCrash);
|
||||
}
|
||||
|
||||
private static void bootCrash(int p_85413_, long p_85414_) {
|
||||
RenderSystem.assertInInitPhase();
|
||||
String s = "GLFW error " + p_85413_ + ": " + MemoryUtil.memUTF8(p_85414_);
|
||||
TinyFileDialogs.tinyfd_messageBox("Minecraft", s + ".\n\nPlease make sure you have up-to-date drivers (see aka.ms/mcdriver for instructions).", "ok", "error", false);
|
||||
throw new Window.WindowInitFailed(s);
|
||||
}
|
||||
|
||||
public void defaultErrorCallback(int p_85383_, long p_85384_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
String s = MemoryUtil.memUTF8(p_85384_);
|
||||
LOGGER.error("########## GL ERROR ##########");
|
||||
LOGGER.error("@ {}", (Object)this.errorSection);
|
||||
LOGGER.error("{}: {}", p_85383_, s);
|
||||
}
|
||||
|
||||
public void setDefaultErrorCallback() {
|
||||
GLFWErrorCallback glfwerrorcallback = GLFW.glfwSetErrorCallback(this.defaultErrorCallback);
|
||||
if (glfwerrorcallback != null) {
|
||||
glfwerrorcallback.free();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void updateVsync(boolean p_85410_) {
|
||||
RenderSystem.assertOnRenderThreadOrInit();
|
||||
this.vsync = p_85410_;
|
||||
GLFW.glfwSwapInterval(p_85410_ ? 1 : 0);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
Callbacks.glfwFreeCallbacks(this.window);
|
||||
this.defaultErrorCallback.close();
|
||||
GLFW.glfwDestroyWindow(this.window);
|
||||
GLFW.glfwTerminate();
|
||||
}
|
||||
|
||||
private void onMove(long p_85389_, int p_85390_, int p_85391_) {
|
||||
this.x = p_85390_;
|
||||
this.y = p_85391_;
|
||||
}
|
||||
|
||||
private void onFramebufferResize(long p_85416_, int p_85417_, int p_85418_) {
|
||||
if (p_85416_ == this.window) {
|
||||
int i = this.getWidth();
|
||||
int j = this.getHeight();
|
||||
if (p_85417_ != 0 && p_85418_ != 0) {
|
||||
this.framebufferWidth = p_85417_;
|
||||
this.framebufferHeight = p_85418_;
|
||||
if (this.getWidth() != i || this.getHeight() != j) {
|
||||
this.eventHandler.resizeDisplay();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshFramebufferSize() {
|
||||
RenderSystem.assertInInitPhase();
|
||||
int[] aint = new int[1];
|
||||
int[] aint1 = new int[1];
|
||||
GLFW.glfwGetFramebufferSize(this.window, aint, aint1);
|
||||
this.framebufferWidth = aint[0] > 0 ? aint[0] : 1;
|
||||
this.framebufferHeight = aint1[0] > 0 ? aint1[0] : 1;
|
||||
if (this.framebufferHeight == 0 || this.framebufferWidth==0) net.minecraftforge.fml.loading.ImmediateWindowHandler.updateFBSize(w->this.framebufferWidth=w, h->this.framebufferHeight=h);
|
||||
}
|
||||
|
||||
private void onResize(long p_85428_, int p_85429_, int p_85430_) {
|
||||
this.width = p_85429_;
|
||||
this.height = p_85430_;
|
||||
}
|
||||
|
||||
private void onFocus(long p_85393_, boolean p_85394_) {
|
||||
if (p_85393_ == this.window) {
|
||||
this.eventHandler.setWindowActive(p_85394_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void onEnter(long p_85420_, boolean p_85421_) {
|
||||
if (p_85421_) {
|
||||
this.eventHandler.cursorEntered();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setFramerateLimit(int p_85381_) {
|
||||
this.framerateLimit = p_85381_;
|
||||
}
|
||||
|
||||
public int getFramerateLimit() {
|
||||
return this.framerateLimit;
|
||||
}
|
||||
|
||||
public void updateDisplay() {
|
||||
RenderSystem.flipFrame(this.window);
|
||||
if (this.fullscreen != this.actuallyFullscreen) {
|
||||
this.actuallyFullscreen = this.fullscreen;
|
||||
this.updateFullscreen(this.vsync);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Optional<VideoMode> getPreferredFullscreenVideoMode() {
|
||||
return this.preferredFullscreenVideoMode;
|
||||
}
|
||||
|
||||
public void setPreferredFullscreenVideoMode(Optional<VideoMode> p_85406_) {
|
||||
boolean flag = !p_85406_.equals(this.preferredFullscreenVideoMode);
|
||||
this.preferredFullscreenVideoMode = p_85406_;
|
||||
if (flag) {
|
||||
this.dirty = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void changeFullscreenVideoMode() {
|
||||
if (this.fullscreen && this.dirty) {
|
||||
this.dirty = false;
|
||||
this.setMode();
|
||||
this.eventHandler.resizeDisplay();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void setMode() {
|
||||
RenderSystem.assertInInitPhase();
|
||||
boolean flag = GLFW.glfwGetWindowMonitor(this.window) != 0L;
|
||||
if (this.fullscreen) {
|
||||
Monitor monitor = this.screenManager.findBestMonitor(this);
|
||||
if (monitor == null) {
|
||||
LOGGER.warn("Failed to find suitable monitor for fullscreen mode");
|
||||
this.fullscreen = false;
|
||||
} else {
|
||||
if (Minecraft.ON_OSX) {
|
||||
MacosUtil.toggleFullscreen(this.window);
|
||||
}
|
||||
|
||||
VideoMode videomode = monitor.getPreferredVidMode(this.preferredFullscreenVideoMode);
|
||||
if (!flag) {
|
||||
this.windowedX = this.x;
|
||||
this.windowedY = this.y;
|
||||
this.windowedWidth = this.width;
|
||||
this.windowedHeight = this.height;
|
||||
}
|
||||
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.width = videomode.getWidth();
|
||||
this.height = videomode.getHeight();
|
||||
GLFW.glfwSetWindowMonitor(this.window, monitor.getMonitor(), this.x, this.y, this.width, this.height, videomode.getRefreshRate());
|
||||
}
|
||||
} else {
|
||||
this.x = this.windowedX;
|
||||
this.y = this.windowedY;
|
||||
this.width = this.windowedWidth;
|
||||
this.height = this.windowedHeight;
|
||||
GLFW.glfwSetWindowMonitor(this.window, 0L, this.x, this.y, this.width, this.height, -1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void toggleFullScreen() {
|
||||
this.fullscreen = !this.fullscreen;
|
||||
}
|
||||
|
||||
public void setWindowed(int p_166448_, int p_166449_) {
|
||||
this.windowedWidth = p_166448_;
|
||||
this.windowedHeight = p_166449_;
|
||||
this.fullscreen = false;
|
||||
this.setMode();
|
||||
}
|
||||
|
||||
private void updateFullscreen(boolean p_85432_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
|
||||
try {
|
||||
this.setMode();
|
||||
this.eventHandler.resizeDisplay();
|
||||
this.updateVsync(p_85432_);
|
||||
this.updateDisplay();
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Couldn't toggle fullscreen", (Throwable)exception);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int calculateScale(int p_85386_, boolean p_85387_) {
|
||||
int i;
|
||||
for(i = 1; i != p_85386_ && i < this.framebufferWidth && i < this.framebufferHeight && this.framebufferWidth / (i + 1) >= 320 && this.framebufferHeight / (i + 1) >= 240; ++i) {
|
||||
}
|
||||
|
||||
if (p_85387_ && i % 2 != 0) {
|
||||
++i;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public void setGuiScale(double p_85379_) {
|
||||
this.guiScale = p_85379_;
|
||||
int i = (int)((double)this.framebufferWidth / p_85379_);
|
||||
this.guiScaledWidth = (double)this.framebufferWidth / p_85379_ > (double)i ? i + 1 : i;
|
||||
int j = (int)((double)this.framebufferHeight / p_85379_);
|
||||
this.guiScaledHeight = (double)this.framebufferHeight / p_85379_ > (double)j ? j + 1 : j;
|
||||
}
|
||||
|
||||
public void setTitle(String p_85423_) {
|
||||
GLFW.glfwSetWindowTitle(this.window, p_85423_);
|
||||
}
|
||||
|
||||
public long getWindow() {
|
||||
return this.window;
|
||||
}
|
||||
|
||||
public boolean isFullscreen() {
|
||||
return this.fullscreen;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return this.framebufferWidth;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return this.framebufferHeight;
|
||||
}
|
||||
|
||||
public void setWidth(int p_166451_) {
|
||||
this.framebufferWidth = p_166451_;
|
||||
}
|
||||
|
||||
public void setHeight(int p_166453_) {
|
||||
this.framebufferHeight = p_166453_;
|
||||
}
|
||||
|
||||
public int getScreenWidth() {
|
||||
return this.width;
|
||||
}
|
||||
|
||||
public int getScreenHeight() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
public int getGuiScaledWidth() {
|
||||
return this.guiScaledWidth;
|
||||
}
|
||||
|
||||
public int getGuiScaledHeight() {
|
||||
return this.guiScaledHeight;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
public double getGuiScale() {
|
||||
return this.guiScale;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Monitor findBestMonitor() {
|
||||
return this.screenManager.findBestMonitor(this);
|
||||
}
|
||||
|
||||
public void updateRawMouseInput(boolean p_85425_) {
|
||||
InputConstants.updateRawMouseInput(this.window, p_85425_);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class WindowInitFailed extends SilentInitException {
|
||||
WindowInitFailed(String p_85455_) {
|
||||
super(p_85455_);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.mojang.blaze3d.platform;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface WindowEventHandler {
|
||||
void setWindowActive(boolean p_85477_);
|
||||
|
||||
void resizeDisplay();
|
||||
|
||||
void cursorEntered();
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
package com.mojang.blaze3d.platform;
|
||||
|
||||
import com.mojang.blaze3d.FieldsAreNonnullByDefault;
|
||||
import com.mojang.blaze3d.MethodsReturnNonnullByDefault;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.mojang.blaze3d.preprocessor;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Lists;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.FileUtil;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.util.StringUtil;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public abstract class GlslPreprocessor {
|
||||
private static final String C_COMMENT = "/\\*(?:[^*]|\\*+[^*/])*\\*+/";
|
||||
private static final String LINE_COMMENT = "//[^\\v]*";
|
||||
private static final Pattern REGEX_MOJ_IMPORT = Pattern.compile("(#(?:/\\*(?:[^*]|\\*+[^*/])*\\*+/|\\h)*moj_import(?:/\\*(?:[^*]|\\*+[^*/])*\\*+/|\\h)*(?:\"(.*)\"|<(.*)>))");
|
||||
private static final Pattern REGEX_VERSION = Pattern.compile("(#(?:/\\*(?:[^*]|\\*+[^*/])*\\*+/|\\h)*version(?:/\\*(?:[^*]|\\*+[^*/])*\\*+/|\\h)*(\\d+))\\b");
|
||||
private static final Pattern REGEX_ENDS_WITH_WHITESPACE = Pattern.compile("(?:^|\\v)(?:\\s|/\\*(?:[^*]|\\*+[^*/])*\\*+/|(//[^\\v]*))*\\z");
|
||||
|
||||
public List<String> process(String p_166462_) {
|
||||
GlslPreprocessor.Context glslpreprocessor$context = new GlslPreprocessor.Context();
|
||||
List<String> list = this.processImports(p_166462_, glslpreprocessor$context, "");
|
||||
list.set(0, this.setVersion(list.get(0), glslpreprocessor$context.glslVersion));
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<String> processImports(String p_166470_, GlslPreprocessor.Context p_166471_, String p_166472_) {
|
||||
int i = p_166471_.sourceId;
|
||||
int j = 0;
|
||||
String s = "";
|
||||
List<String> list = Lists.newArrayList();
|
||||
Matcher matcher = REGEX_MOJ_IMPORT.matcher(p_166470_);
|
||||
|
||||
while(matcher.find()) {
|
||||
if (!isDirectiveDisabled(p_166470_, matcher, j)) {
|
||||
String s1 = matcher.group(2);
|
||||
boolean flag = s1 != null;
|
||||
if (!flag) {
|
||||
s1 = matcher.group(3);
|
||||
}
|
||||
|
||||
if (s1 != null) {
|
||||
String s2 = p_166470_.substring(j, matcher.start(1));
|
||||
String s3 = p_166472_ + s1;
|
||||
String s4 = this.applyImport(flag, s3);
|
||||
if (!Strings.isNullOrEmpty(s4)) {
|
||||
if (!StringUtil.endsWithNewLine(s4)) {
|
||||
s4 = s4 + System.lineSeparator();
|
||||
}
|
||||
|
||||
++p_166471_.sourceId;
|
||||
int k = p_166471_.sourceId;
|
||||
List<String> list1 = this.processImports(s4, p_166471_, flag ? FileUtil.getFullResourcePath(s3) : "");
|
||||
list1.set(0, String.format(Locale.ROOT, "#line %d %d\n%s", 0, k, this.processVersions(list1.get(0), p_166471_)));
|
||||
if (!Util.isBlank(s2)) {
|
||||
list.add(s2);
|
||||
}
|
||||
|
||||
list.addAll(list1);
|
||||
} else {
|
||||
String s6 = flag ? String.format(Locale.ROOT, "/*#moj_import \"%s\"*/", s1) : String.format(Locale.ROOT, "/*#moj_import <%s>*/", s1);
|
||||
list.add(s + s2 + s6);
|
||||
}
|
||||
|
||||
int l = StringUtil.lineCount(p_166470_.substring(0, matcher.end(1)));
|
||||
s = String.format(Locale.ROOT, "#line %d %d", l, i);
|
||||
j = matcher.end(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String s5 = p_166470_.substring(j);
|
||||
if (!Util.isBlank(s5)) {
|
||||
list.add(s + s5);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private String processVersions(String p_166467_, GlslPreprocessor.Context p_166468_) {
|
||||
Matcher matcher = REGEX_VERSION.matcher(p_166467_);
|
||||
if (matcher.find() && isDirectiveEnabled(p_166467_, matcher)) {
|
||||
p_166468_.glslVersion = Math.max(p_166468_.glslVersion, Integer.parseInt(matcher.group(2)));
|
||||
return p_166467_.substring(0, matcher.start(1)) + "/*" + p_166467_.substring(matcher.start(1), matcher.end(1)) + "*/" + p_166467_.substring(matcher.end(1));
|
||||
} else {
|
||||
return p_166467_;
|
||||
}
|
||||
}
|
||||
|
||||
private String setVersion(String p_166464_, int p_166465_) {
|
||||
Matcher matcher = REGEX_VERSION.matcher(p_166464_);
|
||||
return matcher.find() && isDirectiveEnabled(p_166464_, matcher) ? p_166464_.substring(0, matcher.start(2)) + Math.max(p_166465_, Integer.parseInt(matcher.group(2))) + p_166464_.substring(matcher.end(2)) : p_166464_;
|
||||
}
|
||||
|
||||
private static boolean isDirectiveEnabled(String p_166474_, Matcher p_166475_) {
|
||||
return !isDirectiveDisabled(p_166474_, p_166475_, 0);
|
||||
}
|
||||
|
||||
private static boolean isDirectiveDisabled(String p_166477_, Matcher p_166478_, int p_166479_) {
|
||||
int i = p_166478_.start() - p_166479_;
|
||||
if (i == 0) {
|
||||
return false;
|
||||
} else {
|
||||
Matcher matcher = REGEX_ENDS_WITH_WHITESPACE.matcher(p_166477_.substring(p_166479_, p_166478_.start()));
|
||||
if (!matcher.find()) {
|
||||
return true;
|
||||
} else {
|
||||
int j = matcher.end(1);
|
||||
return j == p_166478_.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public abstract String applyImport(boolean p_166480_, String p_166481_);
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static final class Context {
|
||||
int glslVersion;
|
||||
int sourceId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
package com.mojang.blaze3d.preprocessor;
|
||||
|
||||
import com.mojang.blaze3d.FieldsAreNonnullByDefault;
|
||||
import com.mojang.blaze3d.MethodsReturnNonnullByDefault;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.mojang.blaze3d.shaders;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.joml.Matrix3f;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4f;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class AbstractUniform {
|
||||
public void set(float p_85479_) {
|
||||
}
|
||||
|
||||
public void set(float p_85480_, float p_85481_) {
|
||||
}
|
||||
|
||||
public void set(float p_85482_, float p_85483_, float p_85484_) {
|
||||
}
|
||||
|
||||
public void set(float p_85485_, float p_85486_, float p_85487_, float p_85488_) {
|
||||
}
|
||||
|
||||
public void setSafe(float p_85495_, float p_85496_, float p_85497_, float p_85498_) {
|
||||
}
|
||||
|
||||
public void setSafe(int p_85489_, int p_85490_, int p_85491_, int p_85492_) {
|
||||
}
|
||||
|
||||
public void set(int p_166536_) {
|
||||
}
|
||||
|
||||
public void set(int p_166537_, int p_166538_) {
|
||||
}
|
||||
|
||||
public void set(int p_166539_, int p_166540_, int p_166541_) {
|
||||
}
|
||||
|
||||
public void set(int p_166570_, int p_166571_, int p_166572_, int p_166573_) {
|
||||
}
|
||||
|
||||
public void set(float[] p_85494_) {
|
||||
}
|
||||
|
||||
public void set(Vector3f p_254315_) {
|
||||
}
|
||||
|
||||
public void set(Vector4f p_254449_) {
|
||||
}
|
||||
|
||||
public void setMat2x2(float p_166574_, float p_166575_, float p_166576_, float p_166577_) {
|
||||
}
|
||||
|
||||
public void setMat2x3(float p_166485_, float p_166486_, float p_166487_, float p_166488_, float p_166489_, float p_166490_) {
|
||||
}
|
||||
|
||||
public void setMat2x4(float p_166491_, float p_166492_, float p_166493_, float p_166494_, float p_166495_, float p_166496_, float p_166497_, float p_166498_) {
|
||||
}
|
||||
|
||||
public void setMat3x2(float p_166544_, float p_166545_, float p_166546_, float p_166547_, float p_166548_, float p_166549_) {
|
||||
}
|
||||
|
||||
public void setMat3x3(float p_166499_, float p_166500_, float p_166501_, float p_166502_, float p_166503_, float p_166504_, float p_166505_, float p_166506_, float p_166507_) {
|
||||
}
|
||||
|
||||
public void setMat3x4(float p_166508_, float p_166509_, float p_166510_, float p_166511_, float p_166512_, float p_166513_, float p_166514_, float p_166515_, float p_166516_, float p_166517_, float p_166518_, float p_166519_) {
|
||||
}
|
||||
|
||||
public void setMat4x2(float p_166550_, float p_166551_, float p_166552_, float p_166553_, float p_166554_, float p_166555_, float p_166556_, float p_166557_) {
|
||||
}
|
||||
|
||||
public void setMat4x3(float p_166558_, float p_166559_, float p_166560_, float p_166561_, float p_166562_, float p_166563_, float p_166564_, float p_166565_, float p_166566_, float p_166567_, float p_166568_, float p_166569_) {
|
||||
}
|
||||
|
||||
public void setMat4x4(float p_166520_, float p_166521_, float p_166522_, float p_166523_, float p_166524_, float p_166525_, float p_166526_, float p_166527_, float p_166528_, float p_166529_, float p_166530_, float p_166531_, float p_166532_, float p_166533_, float p_166534_, float p_166535_) {
|
||||
}
|
||||
|
||||
public void set(Matrix4f p_254214_) {
|
||||
}
|
||||
|
||||
public void set(Matrix3f p_254112_) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
package com.mojang.blaze3d.shaders;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import java.util.Locale;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class BlendMode {
|
||||
@Nullable
|
||||
private static BlendMode lastApplied;
|
||||
private final int srcColorFactor;
|
||||
private final int srcAlphaFactor;
|
||||
private final int dstColorFactor;
|
||||
private final int dstAlphaFactor;
|
||||
private final int blendFunc;
|
||||
private final boolean separateBlend;
|
||||
private final boolean opaque;
|
||||
|
||||
private BlendMode(boolean p_85519_, boolean p_85520_, int p_85521_, int p_85522_, int p_85523_, int p_85524_, int p_85525_) {
|
||||
this.separateBlend = p_85519_;
|
||||
this.srcColorFactor = p_85521_;
|
||||
this.dstColorFactor = p_85522_;
|
||||
this.srcAlphaFactor = p_85523_;
|
||||
this.dstAlphaFactor = p_85524_;
|
||||
this.opaque = p_85520_;
|
||||
this.blendFunc = p_85525_;
|
||||
}
|
||||
|
||||
public BlendMode() {
|
||||
this(false, true, 1, 0, 1, 0, 32774);
|
||||
}
|
||||
|
||||
public BlendMode(int p_85509_, int p_85510_, int p_85511_) {
|
||||
this(false, false, p_85509_, p_85510_, p_85509_, p_85510_, p_85511_);
|
||||
}
|
||||
|
||||
public BlendMode(int p_85513_, int p_85514_, int p_85515_, int p_85516_, int p_85517_) {
|
||||
this(true, false, p_85513_, p_85514_, p_85515_, p_85516_, p_85517_);
|
||||
}
|
||||
|
||||
public void apply() {
|
||||
if (!this.equals(lastApplied)) {
|
||||
if (lastApplied == null || this.opaque != lastApplied.isOpaque()) {
|
||||
lastApplied = this;
|
||||
if (this.opaque) {
|
||||
RenderSystem.disableBlend();
|
||||
return;
|
||||
}
|
||||
|
||||
RenderSystem.enableBlend();
|
||||
}
|
||||
|
||||
RenderSystem.blendEquation(this.blendFunc);
|
||||
if (this.separateBlend) {
|
||||
RenderSystem.blendFuncSeparate(this.srcColorFactor, this.dstColorFactor, this.srcAlphaFactor, this.dstAlphaFactor);
|
||||
} else {
|
||||
RenderSystem.blendFunc(this.srcColorFactor, this.dstColorFactor);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public boolean equals(Object p_85533_) {
|
||||
if (this == p_85533_) {
|
||||
return true;
|
||||
} else if (!(p_85533_ instanceof BlendMode)) {
|
||||
return false;
|
||||
} else {
|
||||
BlendMode blendmode = (BlendMode)p_85533_;
|
||||
if (this.blendFunc != blendmode.blendFunc) {
|
||||
return false;
|
||||
} else if (this.dstAlphaFactor != blendmode.dstAlphaFactor) {
|
||||
return false;
|
||||
} else if (this.dstColorFactor != blendmode.dstColorFactor) {
|
||||
return false;
|
||||
} else if (this.opaque != blendmode.opaque) {
|
||||
return false;
|
||||
} else if (this.separateBlend != blendmode.separateBlend) {
|
||||
return false;
|
||||
} else if (this.srcAlphaFactor != blendmode.srcAlphaFactor) {
|
||||
return false;
|
||||
} else {
|
||||
return this.srcColorFactor == blendmode.srcColorFactor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int i = this.srcColorFactor;
|
||||
i = 31 * i + this.srcAlphaFactor;
|
||||
i = 31 * i + this.dstColorFactor;
|
||||
i = 31 * i + this.dstAlphaFactor;
|
||||
i = 31 * i + this.blendFunc;
|
||||
i = 31 * i + (this.separateBlend ? 1 : 0);
|
||||
return 31 * i + (this.opaque ? 1 : 0);
|
||||
}
|
||||
|
||||
public boolean isOpaque() {
|
||||
return this.opaque;
|
||||
}
|
||||
|
||||
public static int stringToBlendFunc(String p_85528_) {
|
||||
String s = p_85528_.trim().toLowerCase(Locale.ROOT);
|
||||
if ("add".equals(s)) {
|
||||
return 32774;
|
||||
} else if ("subtract".equals(s)) {
|
||||
return 32778;
|
||||
} else if ("reversesubtract".equals(s)) {
|
||||
return 32779;
|
||||
} else if ("reverse_subtract".equals(s)) {
|
||||
return 32779;
|
||||
} else if ("min".equals(s)) {
|
||||
return 32775;
|
||||
} else {
|
||||
return "max".equals(s) ? '\u8008' : '\u8006';
|
||||
}
|
||||
}
|
||||
|
||||
public static int stringToBlendFactor(String p_85531_) {
|
||||
String s = p_85531_.trim().toLowerCase(Locale.ROOT);
|
||||
s = s.replaceAll("_", "");
|
||||
s = s.replaceAll("one", "1");
|
||||
s = s.replaceAll("zero", "0");
|
||||
s = s.replaceAll("minus", "-");
|
||||
if ("0".equals(s)) {
|
||||
return 0;
|
||||
} else if ("1".equals(s)) {
|
||||
return 1;
|
||||
} else if ("srccolor".equals(s)) {
|
||||
return 768;
|
||||
} else if ("1-srccolor".equals(s)) {
|
||||
return 769;
|
||||
} else if ("dstcolor".equals(s)) {
|
||||
return 774;
|
||||
} else if ("1-dstcolor".equals(s)) {
|
||||
return 775;
|
||||
} else if ("srcalpha".equals(s)) {
|
||||
return 770;
|
||||
} else if ("1-srcalpha".equals(s)) {
|
||||
return 771;
|
||||
} else if ("dstalpha".equals(s)) {
|
||||
return 772;
|
||||
} else {
|
||||
return "1-dstalpha".equals(s) ? 773 : -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.mojang.blaze3d.shaders;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface Effect extends Shader {
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.mojang.blaze3d.shaders;
|
||||
|
||||
import com.mojang.blaze3d.preprocessor.GlslPreprocessor;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class EffectProgram extends Program {
|
||||
private static final GlslPreprocessor PREPROCESSOR = new GlslPreprocessor() {
|
||||
public String applyImport(boolean p_166595_, String p_166596_) {
|
||||
return "#error Import statement not supported";
|
||||
}
|
||||
};
|
||||
private int references;
|
||||
|
||||
private EffectProgram(Program.Type p_166582_, int p_166583_, String p_166584_) {
|
||||
super(p_166582_, p_166583_, p_166584_);
|
||||
}
|
||||
|
||||
public void attachToEffect(Effect p_166587_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
++this.references;
|
||||
this.attachToShader(p_166587_);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
--this.references;
|
||||
if (this.references <= 0) {
|
||||
super.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static EffectProgram compileShader(Program.Type p_166589_, String p_166590_, InputStream p_166591_, String p_166592_) throws IOException {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
int i = compileShaderInternal(p_166589_, p_166590_, p_166591_, p_166592_, PREPROCESSOR);
|
||||
EffectProgram effectprogram = new EffectProgram(p_166589_, i, p_166590_);
|
||||
p_166589_.getPrograms().put(p_166590_, effectprogram);
|
||||
return effectprogram;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.mojang.blaze3d.shaders;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public enum FogShape {
|
||||
SPHERE(0),
|
||||
CYLINDER(1);
|
||||
|
||||
private final int index;
|
||||
|
||||
private FogShape(int p_202323_) {
|
||||
this.index = p_202323_;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return this.index;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package com.mojang.blaze3d.shaders;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.preprocessor.GlslPreprocessor;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class Program {
|
||||
private static final int MAX_LOG_LENGTH = 32768;
|
||||
private final Program.Type type;
|
||||
private final String name;
|
||||
private int id;
|
||||
|
||||
protected Program(Program.Type p_85540_, int p_85541_, String p_85542_) {
|
||||
this.type = p_85540_;
|
||||
this.id = p_85541_;
|
||||
this.name = p_85542_;
|
||||
}
|
||||
|
||||
public void attachToShader(Shader p_166611_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GlStateManager.glAttachShader(p_166611_.getId(), this.getId());
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (this.id != -1) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GlStateManager.glDeleteShader(this.id);
|
||||
this.id = -1;
|
||||
this.type.getPrograms().remove(this.name);
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public static Program compileShader(Program.Type p_166605_, String p_166606_, InputStream p_166607_, String p_166608_, GlslPreprocessor p_166609_) throws IOException {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
int i = compileShaderInternal(p_166605_, p_166606_, p_166607_, p_166608_, p_166609_);
|
||||
Program program = new Program(p_166605_, i, p_166606_);
|
||||
p_166605_.getPrograms().put(p_166606_, program);
|
||||
return program;
|
||||
}
|
||||
|
||||
protected static int compileShaderInternal(Program.Type p_166613_, String p_166614_, InputStream p_166615_, String p_166616_, GlslPreprocessor p_166617_) throws IOException {
|
||||
String s = IOUtils.toString(p_166615_, StandardCharsets.UTF_8);
|
||||
if (s == null) {
|
||||
throw new IOException("Could not load program " + p_166613_.getName());
|
||||
} else {
|
||||
int i = GlStateManager.glCreateShader(p_166613_.getGlType());
|
||||
GlStateManager.glShaderSource(i, p_166617_.process(s));
|
||||
GlStateManager.glCompileShader(i);
|
||||
if (GlStateManager.glGetShaderi(i, 35713) == 0) {
|
||||
String s1 = StringUtils.trim(GlStateManager.glGetShaderInfoLog(i, 32768));
|
||||
throw new IOException("Couldn't compile " + p_166613_.getName() + " program (" + p_166616_ + ", " + p_166614_ + ") : " + s1);
|
||||
} else {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum Type {
|
||||
VERTEX("vertex", ".vsh", 35633),
|
||||
FRAGMENT("fragment", ".fsh", 35632);
|
||||
|
||||
private final String name;
|
||||
private final String extension;
|
||||
private final int glType;
|
||||
private final Map<String, Program> programs = Maps.newHashMap();
|
||||
|
||||
private Type(String p_85563_, String p_85564_, int p_85565_) {
|
||||
this.name = p_85563_;
|
||||
this.extension = p_85564_;
|
||||
this.glType = p_85565_;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getExtension() {
|
||||
return this.extension;
|
||||
}
|
||||
|
||||
int getGlType() {
|
||||
return this.glType;
|
||||
}
|
||||
|
||||
public Map<String, Program> getPrograms() {
|
||||
return this.programs;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.mojang.blaze3d.shaders;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.io.IOException;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class ProgramManager {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
public static void glUseProgram(int p_85579_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
GlStateManager._glUseProgram(p_85579_);
|
||||
}
|
||||
|
||||
public static void releaseProgram(Shader p_166622_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
p_166622_.getFragmentProgram().close();
|
||||
p_166622_.getVertexProgram().close();
|
||||
GlStateManager.glDeleteProgram(p_166622_.getId());
|
||||
}
|
||||
|
||||
public static int createProgram() throws IOException {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
int i = GlStateManager.glCreateProgram();
|
||||
if (i <= 0) {
|
||||
throw new IOException("Could not create shader program (returned program ID " + i + ")");
|
||||
} else {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
public static void linkShader(Shader p_166624_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
p_166624_.attachToProgram();
|
||||
GlStateManager.glLinkProgram(p_166624_.getId());
|
||||
int i = GlStateManager.glGetProgrami(p_166624_.getId(), 35714);
|
||||
if (i == 0) {
|
||||
LOGGER.warn("Error encountered when linking program containing VS {} and FS {}. Log output:", p_166624_.getVertexProgram().getName(), p_166624_.getFragmentProgram().getName());
|
||||
LOGGER.warn(GlStateManager.glGetProgramInfoLog(p_166624_.getId(), 32768));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.mojang.blaze3d.shaders;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface Shader {
|
||||
int getId();
|
||||
|
||||
void markDirty();
|
||||
|
||||
Program getVertexProgram();
|
||||
|
||||
Program getFragmentProgram();
|
||||
|
||||
void attachToProgram();
|
||||
}
|
||||
@@ -0,0 +1,486 @@
|
||||
package com.mojang.blaze3d.shaders;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.joml.Matrix3f;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4f;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class Uniform extends AbstractUniform implements AutoCloseable {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
public static final int UT_INT1 = 0;
|
||||
public static final int UT_INT2 = 1;
|
||||
public static final int UT_INT3 = 2;
|
||||
public static final int UT_INT4 = 3;
|
||||
public static final int UT_FLOAT1 = 4;
|
||||
public static final int UT_FLOAT2 = 5;
|
||||
public static final int UT_FLOAT3 = 6;
|
||||
public static final int UT_FLOAT4 = 7;
|
||||
public static final int UT_MAT2 = 8;
|
||||
public static final int UT_MAT3 = 9;
|
||||
public static final int UT_MAT4 = 10;
|
||||
private static final boolean TRANSPOSE_MATRICIES = false;
|
||||
private int location;
|
||||
private final int count;
|
||||
private final int type;
|
||||
private final IntBuffer intValues;
|
||||
private final FloatBuffer floatValues;
|
||||
private final String name;
|
||||
private boolean dirty;
|
||||
private final Shader parent;
|
||||
|
||||
public Uniform(String p_166638_, int p_166639_, int p_166640_, Shader p_166641_) {
|
||||
this.name = p_166638_;
|
||||
this.count = p_166640_;
|
||||
this.type = p_166639_;
|
||||
this.parent = p_166641_;
|
||||
if (p_166639_ <= 3) {
|
||||
this.intValues = MemoryUtil.memAllocInt(p_166640_);
|
||||
this.floatValues = null;
|
||||
} else {
|
||||
this.intValues = null;
|
||||
this.floatValues = MemoryUtil.memAllocFloat(p_166640_);
|
||||
}
|
||||
|
||||
this.location = -1;
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public static int glGetUniformLocation(int p_85625_, CharSequence p_85626_) {
|
||||
return GlStateManager._glGetUniformLocation(p_85625_, p_85626_);
|
||||
}
|
||||
|
||||
public static void uploadInteger(int p_85617_, int p_85618_) {
|
||||
RenderSystem.glUniform1i(p_85617_, p_85618_);
|
||||
}
|
||||
|
||||
public static int glGetAttribLocation(int p_85640_, CharSequence p_85641_) {
|
||||
return GlStateManager._glGetAttribLocation(p_85640_, p_85641_);
|
||||
}
|
||||
|
||||
public static void glBindAttribLocation(int p_166711_, int p_166712_, CharSequence p_166713_) {
|
||||
GlStateManager._glBindAttribLocation(p_166711_, p_166712_, p_166713_);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (this.intValues != null) {
|
||||
MemoryUtil.memFree(this.intValues);
|
||||
}
|
||||
|
||||
if (this.floatValues != null) {
|
||||
MemoryUtil.memFree(this.floatValues);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void markDirty() {
|
||||
this.dirty = true;
|
||||
if (this.parent != null) {
|
||||
this.parent.markDirty();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static int getTypeFromString(String p_85630_) {
|
||||
int i = -1;
|
||||
if ("int".equals(p_85630_)) {
|
||||
i = 0;
|
||||
} else if ("float".equals(p_85630_)) {
|
||||
i = 4;
|
||||
} else if (p_85630_.startsWith("matrix")) {
|
||||
if (p_85630_.endsWith("2x2")) {
|
||||
i = 8;
|
||||
} else if (p_85630_.endsWith("3x3")) {
|
||||
i = 9;
|
||||
} else if (p_85630_.endsWith("4x4")) {
|
||||
i = 10;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public void setLocation(int p_85615_) {
|
||||
this.location = p_85615_;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public final void set(float p_85601_) {
|
||||
this.floatValues.position(0);
|
||||
this.floatValues.put(0, p_85601_);
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public final void set(float p_85603_, float p_85604_) {
|
||||
this.floatValues.position(0);
|
||||
this.floatValues.put(0, p_85603_);
|
||||
this.floatValues.put(1, p_85604_);
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public final void set(int p_166701_, float p_166702_) {
|
||||
this.floatValues.position(0);
|
||||
this.floatValues.put(p_166701_, p_166702_);
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public final void set(float p_85606_, float p_85607_, float p_85608_) {
|
||||
this.floatValues.position(0);
|
||||
this.floatValues.put(0, p_85606_);
|
||||
this.floatValues.put(1, p_85607_);
|
||||
this.floatValues.put(2, p_85608_);
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public final void set(Vector3f p_253931_) {
|
||||
this.floatValues.position(0);
|
||||
p_253931_.get(this.floatValues);
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public final void set(float p_85610_, float p_85611_, float p_85612_, float p_85613_) {
|
||||
this.floatValues.position(0);
|
||||
this.floatValues.put(p_85610_);
|
||||
this.floatValues.put(p_85611_);
|
||||
this.floatValues.put(p_85612_);
|
||||
this.floatValues.put(p_85613_);
|
||||
this.floatValues.flip();
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public final void set(Vector4f p_254360_) {
|
||||
this.floatValues.position(0);
|
||||
p_254360_.get(this.floatValues);
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public final void setSafe(float p_85635_, float p_85636_, float p_85637_, float p_85638_) {
|
||||
this.floatValues.position(0);
|
||||
if (this.type >= 4) {
|
||||
this.floatValues.put(0, p_85635_);
|
||||
}
|
||||
|
||||
if (this.type >= 5) {
|
||||
this.floatValues.put(1, p_85636_);
|
||||
}
|
||||
|
||||
if (this.type >= 6) {
|
||||
this.floatValues.put(2, p_85637_);
|
||||
}
|
||||
|
||||
if (this.type >= 7) {
|
||||
this.floatValues.put(3, p_85638_);
|
||||
}
|
||||
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public final void setSafe(int p_85620_, int p_85621_, int p_85622_, int p_85623_) {
|
||||
this.intValues.position(0);
|
||||
if (this.type >= 0) {
|
||||
this.intValues.put(0, p_85620_);
|
||||
}
|
||||
|
||||
if (this.type >= 1) {
|
||||
this.intValues.put(1, p_85621_);
|
||||
}
|
||||
|
||||
if (this.type >= 2) {
|
||||
this.intValues.put(2, p_85622_);
|
||||
}
|
||||
|
||||
if (this.type >= 3) {
|
||||
this.intValues.put(3, p_85623_);
|
||||
}
|
||||
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public final void set(int p_166699_) {
|
||||
this.intValues.position(0);
|
||||
this.intValues.put(0, p_166699_);
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public final void set(int p_166704_, int p_166705_) {
|
||||
this.intValues.position(0);
|
||||
this.intValues.put(0, p_166704_);
|
||||
this.intValues.put(1, p_166705_);
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public final void set(int p_166707_, int p_166708_, int p_166709_) {
|
||||
this.intValues.position(0);
|
||||
this.intValues.put(0, p_166707_);
|
||||
this.intValues.put(1, p_166708_);
|
||||
this.intValues.put(2, p_166709_);
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public final void set(int p_166748_, int p_166749_, int p_166750_, int p_166751_) {
|
||||
this.intValues.position(0);
|
||||
this.intValues.put(0, p_166748_);
|
||||
this.intValues.put(1, p_166749_);
|
||||
this.intValues.put(2, p_166750_);
|
||||
this.intValues.put(3, p_166751_);
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public final void set(float[] p_85632_) {
|
||||
if (p_85632_.length < this.count) {
|
||||
LOGGER.warn("Uniform.set called with a too-small value array (expected {}, got {}). Ignoring.", this.count, p_85632_.length);
|
||||
} else {
|
||||
this.floatValues.position(0);
|
||||
this.floatValues.put(p_85632_);
|
||||
this.floatValues.position(0);
|
||||
this.markDirty();
|
||||
}
|
||||
}
|
||||
|
||||
public final void setMat2x2(float p_166754_, float p_166755_, float p_166756_, float p_166757_) {
|
||||
this.floatValues.position(0);
|
||||
this.floatValues.put(0, p_166754_);
|
||||
this.floatValues.put(1, p_166755_);
|
||||
this.floatValues.put(2, p_166756_);
|
||||
this.floatValues.put(3, p_166757_);
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public final void setMat2x3(float p_166643_, float p_166644_, float p_166645_, float p_166646_, float p_166647_, float p_166648_) {
|
||||
this.floatValues.position(0);
|
||||
this.floatValues.put(0, p_166643_);
|
||||
this.floatValues.put(1, p_166644_);
|
||||
this.floatValues.put(2, p_166645_);
|
||||
this.floatValues.put(3, p_166646_);
|
||||
this.floatValues.put(4, p_166647_);
|
||||
this.floatValues.put(5, p_166648_);
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public final void setMat2x4(float p_166650_, float p_166651_, float p_166652_, float p_166653_, float p_166654_, float p_166655_, float p_166656_, float p_166657_) {
|
||||
this.floatValues.position(0);
|
||||
this.floatValues.put(0, p_166650_);
|
||||
this.floatValues.put(1, p_166651_);
|
||||
this.floatValues.put(2, p_166652_);
|
||||
this.floatValues.put(3, p_166653_);
|
||||
this.floatValues.put(4, p_166654_);
|
||||
this.floatValues.put(5, p_166655_);
|
||||
this.floatValues.put(6, p_166656_);
|
||||
this.floatValues.put(7, p_166657_);
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public final void setMat3x2(float p_166719_, float p_166720_, float p_166721_, float p_166722_, float p_166723_, float p_166724_) {
|
||||
this.floatValues.position(0);
|
||||
this.floatValues.put(0, p_166719_);
|
||||
this.floatValues.put(1, p_166720_);
|
||||
this.floatValues.put(2, p_166721_);
|
||||
this.floatValues.put(3, p_166722_);
|
||||
this.floatValues.put(4, p_166723_);
|
||||
this.floatValues.put(5, p_166724_);
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public final void setMat3x3(float p_166659_, float p_166660_, float p_166661_, float p_166662_, float p_166663_, float p_166664_, float p_166665_, float p_166666_, float p_166667_) {
|
||||
this.floatValues.position(0);
|
||||
this.floatValues.put(0, p_166659_);
|
||||
this.floatValues.put(1, p_166660_);
|
||||
this.floatValues.put(2, p_166661_);
|
||||
this.floatValues.put(3, p_166662_);
|
||||
this.floatValues.put(4, p_166663_);
|
||||
this.floatValues.put(5, p_166664_);
|
||||
this.floatValues.put(6, p_166665_);
|
||||
this.floatValues.put(7, p_166666_);
|
||||
this.floatValues.put(8, p_166667_);
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public final void setMat3x4(float p_166669_, float p_166670_, float p_166671_, float p_166672_, float p_166673_, float p_166674_, float p_166675_, float p_166676_, float p_166677_, float p_166678_, float p_166679_, float p_166680_) {
|
||||
this.floatValues.position(0);
|
||||
this.floatValues.put(0, p_166669_);
|
||||
this.floatValues.put(1, p_166670_);
|
||||
this.floatValues.put(2, p_166671_);
|
||||
this.floatValues.put(3, p_166672_);
|
||||
this.floatValues.put(4, p_166673_);
|
||||
this.floatValues.put(5, p_166674_);
|
||||
this.floatValues.put(6, p_166675_);
|
||||
this.floatValues.put(7, p_166676_);
|
||||
this.floatValues.put(8, p_166677_);
|
||||
this.floatValues.put(9, p_166678_);
|
||||
this.floatValues.put(10, p_166679_);
|
||||
this.floatValues.put(11, p_166680_);
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public final void setMat4x2(float p_166726_, float p_166727_, float p_166728_, float p_166729_, float p_166730_, float p_166731_, float p_166732_, float p_166733_) {
|
||||
this.floatValues.position(0);
|
||||
this.floatValues.put(0, p_166726_);
|
||||
this.floatValues.put(1, p_166727_);
|
||||
this.floatValues.put(2, p_166728_);
|
||||
this.floatValues.put(3, p_166729_);
|
||||
this.floatValues.put(4, p_166730_);
|
||||
this.floatValues.put(5, p_166731_);
|
||||
this.floatValues.put(6, p_166732_);
|
||||
this.floatValues.put(7, p_166733_);
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public final void setMat4x3(float p_166735_, float p_166736_, float p_166737_, float p_166738_, float p_166739_, float p_166740_, float p_166741_, float p_166742_, float p_166743_, float p_166744_, float p_166745_, float p_166746_) {
|
||||
this.floatValues.position(0);
|
||||
this.floatValues.put(0, p_166735_);
|
||||
this.floatValues.put(1, p_166736_);
|
||||
this.floatValues.put(2, p_166737_);
|
||||
this.floatValues.put(3, p_166738_);
|
||||
this.floatValues.put(4, p_166739_);
|
||||
this.floatValues.put(5, p_166740_);
|
||||
this.floatValues.put(6, p_166741_);
|
||||
this.floatValues.put(7, p_166742_);
|
||||
this.floatValues.put(8, p_166743_);
|
||||
this.floatValues.put(9, p_166744_);
|
||||
this.floatValues.put(10, p_166745_);
|
||||
this.floatValues.put(11, p_166746_);
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public final void setMat4x4(float p_166682_, float p_166683_, float p_166684_, float p_166685_, float p_166686_, float p_166687_, float p_166688_, float p_166689_, float p_166690_, float p_166691_, float p_166692_, float p_166693_, float p_166694_, float p_166695_, float p_166696_, float p_166697_) {
|
||||
this.floatValues.position(0);
|
||||
this.floatValues.put(0, p_166682_);
|
||||
this.floatValues.put(1, p_166683_);
|
||||
this.floatValues.put(2, p_166684_);
|
||||
this.floatValues.put(3, p_166685_);
|
||||
this.floatValues.put(4, p_166686_);
|
||||
this.floatValues.put(5, p_166687_);
|
||||
this.floatValues.put(6, p_166688_);
|
||||
this.floatValues.put(7, p_166689_);
|
||||
this.floatValues.put(8, p_166690_);
|
||||
this.floatValues.put(9, p_166691_);
|
||||
this.floatValues.put(10, p_166692_);
|
||||
this.floatValues.put(11, p_166693_);
|
||||
this.floatValues.put(12, p_166694_);
|
||||
this.floatValues.put(13, p_166695_);
|
||||
this.floatValues.put(14, p_166696_);
|
||||
this.floatValues.put(15, p_166697_);
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public final void set(Matrix4f p_254249_) {
|
||||
this.floatValues.position(0);
|
||||
p_254249_.get(this.floatValues);
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public final void set(Matrix3f p_254556_) {
|
||||
this.floatValues.position(0);
|
||||
p_254556_.get(this.floatValues);
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public void upload() {
|
||||
if (!this.dirty) {
|
||||
}
|
||||
|
||||
this.dirty = false;
|
||||
if (this.type <= 3) {
|
||||
this.uploadAsInteger();
|
||||
} else if (this.type <= 7) {
|
||||
this.uploadAsFloat();
|
||||
} else {
|
||||
if (this.type > 10) {
|
||||
LOGGER.warn("Uniform.upload called, but type value ({}) is not a valid type. Ignoring.", (int)this.type);
|
||||
return;
|
||||
}
|
||||
|
||||
this.uploadAsMatrix();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void uploadAsInteger() {
|
||||
this.intValues.rewind();
|
||||
switch (this.type) {
|
||||
case 0:
|
||||
RenderSystem.glUniform1(this.location, this.intValues);
|
||||
break;
|
||||
case 1:
|
||||
RenderSystem.glUniform2(this.location, this.intValues);
|
||||
break;
|
||||
case 2:
|
||||
RenderSystem.glUniform3(this.location, this.intValues);
|
||||
break;
|
||||
case 3:
|
||||
RenderSystem.glUniform4(this.location, this.intValues);
|
||||
break;
|
||||
default:
|
||||
LOGGER.warn("Uniform.upload called, but count value ({}) is not in the range of 1 to 4. Ignoring.", (int)this.count);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void uploadAsFloat() {
|
||||
this.floatValues.rewind();
|
||||
switch (this.type) {
|
||||
case 4:
|
||||
RenderSystem.glUniform1(this.location, this.floatValues);
|
||||
break;
|
||||
case 5:
|
||||
RenderSystem.glUniform2(this.location, this.floatValues);
|
||||
break;
|
||||
case 6:
|
||||
RenderSystem.glUniform3(this.location, this.floatValues);
|
||||
break;
|
||||
case 7:
|
||||
RenderSystem.glUniform4(this.location, this.floatValues);
|
||||
break;
|
||||
default:
|
||||
LOGGER.warn("Uniform.upload called, but count value ({}) is not in the range of 1 to 4. Ignoring.", (int)this.count);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void uploadAsMatrix() {
|
||||
this.floatValues.clear();
|
||||
switch (this.type) {
|
||||
case 8:
|
||||
RenderSystem.glUniformMatrix2(this.location, false, this.floatValues);
|
||||
break;
|
||||
case 9:
|
||||
RenderSystem.glUniformMatrix3(this.location, false, this.floatValues);
|
||||
break;
|
||||
case 10:
|
||||
RenderSystem.glUniformMatrix4(this.location, false, this.floatValues);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int getLocation() {
|
||||
return this.location;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return this.count;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public IntBuffer getIntBuffer() {
|
||||
return this.intValues;
|
||||
}
|
||||
|
||||
public FloatBuffer getFloatBuffer() {
|
||||
return this.floatValues;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
package com.mojang.blaze3d.shaders;
|
||||
|
||||
import com.mojang.blaze3d.FieldsAreNonnullByDefault;
|
||||
import com.mojang.blaze3d.MethodsReturnNonnullByDefault;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,96 @@
|
||||
package com.mojang.blaze3d.systems;
|
||||
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.opengl.ARBTimerQuery;
|
||||
import org.lwjgl.opengl.GL;
|
||||
import org.lwjgl.opengl.GL32C;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class TimerQuery {
|
||||
private int nextQueryName;
|
||||
|
||||
public static Optional<TimerQuery> getInstance() {
|
||||
return TimerQuery.TimerQueryLazyLoader.INSTANCE;
|
||||
}
|
||||
|
||||
public void beginProfile() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
if (this.nextQueryName != 0) {
|
||||
throw new IllegalStateException("Current profile not ended");
|
||||
} else {
|
||||
this.nextQueryName = GL32C.glGenQueries();
|
||||
GL32C.glBeginQuery(35007, this.nextQueryName);
|
||||
}
|
||||
}
|
||||
|
||||
public TimerQuery.FrameProfile endProfile() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
if (this.nextQueryName == 0) {
|
||||
throw new IllegalStateException("endProfile called before beginProfile");
|
||||
} else {
|
||||
GL32C.glEndQuery(35007);
|
||||
TimerQuery.FrameProfile timerquery$frameprofile = new TimerQuery.FrameProfile(this.nextQueryName);
|
||||
this.nextQueryName = 0;
|
||||
return timerquery$frameprofile;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class FrameProfile {
|
||||
private static final long NO_RESULT = 0L;
|
||||
private static final long CANCELLED_RESULT = -1L;
|
||||
private final int queryName;
|
||||
private long result;
|
||||
|
||||
FrameProfile(int p_231148_) {
|
||||
this.queryName = p_231148_;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
if (this.result == 0L) {
|
||||
this.result = -1L;
|
||||
GL32C.glDeleteQueries(this.queryName);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
if (this.result != 0L) {
|
||||
return true;
|
||||
} else if (1 == GL32C.glGetQueryObjecti(this.queryName, 34919)) {
|
||||
this.result = ARBTimerQuery.glGetQueryObjecti64(this.queryName, 34918);
|
||||
GL32C.glDeleteQueries(this.queryName);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public long get() {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
if (this.result == 0L) {
|
||||
this.result = ARBTimerQuery.glGetQueryObjecti64(this.queryName, 34918);
|
||||
GL32C.glDeleteQueries(this.queryName);
|
||||
}
|
||||
|
||||
return this.result;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class TimerQueryLazyLoader {
|
||||
static final Optional<TimerQuery> INSTANCE = Optional.ofNullable(instantiate());
|
||||
|
||||
private TimerQueryLazyLoader() {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static TimerQuery instantiate() {
|
||||
return !GL.getCapabilities().GL_ARB_timer_query ? null : new TimerQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
package com.mojang.blaze3d.systems;
|
||||
|
||||
import com.mojang.blaze3d.FieldsAreNonnullByDefault;
|
||||
import com.mojang.blaze3d.MethodsReturnNonnullByDefault;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
@@ -0,0 +1,472 @@
|
||||
package com.mojang.blaze3d.vertex;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.mojang.blaze3d.platform.MemoryTracker;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import it.unimi.dsi.fastutil.ints.IntConsumer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.apache.commons.lang3.mutable.MutableInt;
|
||||
import org.joml.Vector3f;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class BufferBuilder extends DefaultedVertexConsumer implements BufferVertexConsumer {
|
||||
private static final int GROWTH_SIZE = 2097152;
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private ByteBuffer buffer;
|
||||
private int renderedBufferCount;
|
||||
private int renderedBufferPointer;
|
||||
private int nextElementByte;
|
||||
private int vertices;
|
||||
@Nullable
|
||||
private VertexFormatElement currentElement;
|
||||
private int elementIndex;
|
||||
private VertexFormat format;
|
||||
private VertexFormat.Mode mode;
|
||||
private boolean fastFormat;
|
||||
private boolean fullFormat;
|
||||
private boolean building;
|
||||
@Nullable
|
||||
private Vector3f[] sortingPoints;
|
||||
@Nullable
|
||||
private VertexSorting sorting;
|
||||
private boolean indexOnly;
|
||||
|
||||
public BufferBuilder(int p_85664_) {
|
||||
this.buffer = MemoryTracker.create(p_85664_ * 6);
|
||||
}
|
||||
|
||||
private void ensureVertexCapacity() {
|
||||
this.ensureCapacity(this.format.getVertexSize());
|
||||
}
|
||||
|
||||
private void ensureCapacity(int p_85723_) {
|
||||
if (this.nextElementByte + p_85723_ > this.buffer.capacity()) {
|
||||
int i = this.buffer.capacity();
|
||||
int j = i + roundUp(p_85723_);
|
||||
LOGGER.debug("Needed to grow BufferBuilder buffer: Old size {} bytes, new size {} bytes.", i, j);
|
||||
ByteBuffer bytebuffer = MemoryTracker.resize(this.buffer, j);
|
||||
bytebuffer.rewind();
|
||||
this.buffer = bytebuffer;
|
||||
}
|
||||
}
|
||||
|
||||
private static int roundUp(int p_85726_) {
|
||||
int i = 2097152;
|
||||
if (p_85726_ == 0) {
|
||||
return i;
|
||||
} else {
|
||||
if (p_85726_ < 0) {
|
||||
i *= -1;
|
||||
}
|
||||
|
||||
int j = p_85726_ % i;
|
||||
return j == 0 ? p_85726_ : p_85726_ + i - j;
|
||||
}
|
||||
}
|
||||
|
||||
public void setQuadSorting(VertexSorting p_277454_) {
|
||||
if (this.mode == VertexFormat.Mode.QUADS) {
|
||||
this.sorting = p_277454_;
|
||||
if (this.sortingPoints == null) {
|
||||
this.sortingPoints = this.makeQuadSortingPoints();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public BufferBuilder.SortState getSortState() {
|
||||
return new BufferBuilder.SortState(this.mode, this.vertices, this.sortingPoints, this.sorting);
|
||||
}
|
||||
|
||||
public void restoreSortState(BufferBuilder.SortState p_166776_) {
|
||||
this.buffer.rewind();
|
||||
this.mode = p_166776_.mode;
|
||||
this.vertices = p_166776_.vertices;
|
||||
this.nextElementByte = this.renderedBufferPointer;
|
||||
this.sortingPoints = p_166776_.sortingPoints;
|
||||
this.sorting = p_166776_.sorting;
|
||||
this.indexOnly = true;
|
||||
}
|
||||
|
||||
public void begin(VertexFormat.Mode p_166780_, VertexFormat p_166781_) {
|
||||
if (this.building) {
|
||||
throw new IllegalStateException("Already building!");
|
||||
} else {
|
||||
this.building = true;
|
||||
this.mode = p_166780_;
|
||||
this.switchFormat(p_166781_);
|
||||
this.currentElement = p_166781_.getElements().get(0);
|
||||
this.elementIndex = 0;
|
||||
this.buffer.rewind();
|
||||
}
|
||||
}
|
||||
|
||||
private void switchFormat(VertexFormat p_85705_) {
|
||||
if (this.format != p_85705_) {
|
||||
this.format = p_85705_;
|
||||
boolean flag = p_85705_ == DefaultVertexFormat.NEW_ENTITY;
|
||||
boolean flag1 = p_85705_ == DefaultVertexFormat.BLOCK;
|
||||
this.fastFormat = flag || flag1;
|
||||
this.fullFormat = flag;
|
||||
}
|
||||
}
|
||||
|
||||
private IntConsumer intConsumer(int p_231159_, VertexFormat.IndexType p_231160_) {
|
||||
MutableInt mutableint = new MutableInt(p_231159_);
|
||||
IntConsumer intconsumer;
|
||||
switch (p_231160_) {
|
||||
case SHORT:
|
||||
intconsumer = (p_231167_) -> {
|
||||
this.buffer.putShort(mutableint.getAndAdd(2), (short)p_231167_);
|
||||
};
|
||||
break;
|
||||
case INT:
|
||||
intconsumer = (p_231163_) -> {
|
||||
this.buffer.putInt(mutableint.getAndAdd(4), p_231163_);
|
||||
};
|
||||
break;
|
||||
default:
|
||||
throw new IncompatibleClassChangeError();
|
||||
}
|
||||
|
||||
return intconsumer;
|
||||
}
|
||||
|
||||
private Vector3f[] makeQuadSortingPoints() {
|
||||
FloatBuffer floatbuffer = this.buffer.asFloatBuffer();
|
||||
int i = this.renderedBufferPointer / 4;
|
||||
int j = this.format.getIntegerSize();
|
||||
int k = j * this.mode.primitiveStride;
|
||||
int l = this.vertices / this.mode.primitiveStride;
|
||||
Vector3f[] avector3f = new Vector3f[l];
|
||||
|
||||
for(int i1 = 0; i1 < l; ++i1) {
|
||||
float f = floatbuffer.get(i + i1 * k + 0);
|
||||
float f1 = floatbuffer.get(i + i1 * k + 1);
|
||||
float f2 = floatbuffer.get(i + i1 * k + 2);
|
||||
float f3 = floatbuffer.get(i + i1 * k + j * 2 + 0);
|
||||
float f4 = floatbuffer.get(i + i1 * k + j * 2 + 1);
|
||||
float f5 = floatbuffer.get(i + i1 * k + j * 2 + 2);
|
||||
float f6 = (f + f3) / 2.0F;
|
||||
float f7 = (f1 + f4) / 2.0F;
|
||||
float f8 = (f2 + f5) / 2.0F;
|
||||
avector3f[i1] = new Vector3f(f6, f7, f8);
|
||||
}
|
||||
|
||||
return avector3f;
|
||||
}
|
||||
|
||||
private void putSortedQuadIndices(VertexFormat.IndexType p_166787_) {
|
||||
if (this.sortingPoints != null && this.sorting != null) {
|
||||
int[] aint = this.sorting.sort(this.sortingPoints);
|
||||
IntConsumer intconsumer = this.intConsumer(this.nextElementByte, p_166787_);
|
||||
|
||||
for(int i : aint) {
|
||||
intconsumer.accept(i * this.mode.primitiveStride + 0);
|
||||
intconsumer.accept(i * this.mode.primitiveStride + 1);
|
||||
intconsumer.accept(i * this.mode.primitiveStride + 2);
|
||||
intconsumer.accept(i * this.mode.primitiveStride + 2);
|
||||
intconsumer.accept(i * this.mode.primitiveStride + 3);
|
||||
intconsumer.accept(i * this.mode.primitiveStride + 0);
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new IllegalStateException("Sorting state uninitialized");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isCurrentBatchEmpty() {
|
||||
return this.vertices == 0;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BufferBuilder.RenderedBuffer endOrDiscardIfEmpty() {
|
||||
this.ensureDrawing();
|
||||
if (this.isCurrentBatchEmpty()) {
|
||||
this.reset();
|
||||
return null;
|
||||
} else {
|
||||
BufferBuilder.RenderedBuffer bufferbuilder$renderedbuffer = this.storeRenderedBuffer();
|
||||
this.reset();
|
||||
return bufferbuilder$renderedbuffer;
|
||||
}
|
||||
}
|
||||
|
||||
public BufferBuilder.RenderedBuffer end() {
|
||||
this.ensureDrawing();
|
||||
BufferBuilder.RenderedBuffer bufferbuilder$renderedbuffer = this.storeRenderedBuffer();
|
||||
this.reset();
|
||||
return bufferbuilder$renderedbuffer;
|
||||
}
|
||||
|
||||
private void ensureDrawing() {
|
||||
if (!this.building) {
|
||||
throw new IllegalStateException("Not building!");
|
||||
}
|
||||
}
|
||||
|
||||
private BufferBuilder.RenderedBuffer storeRenderedBuffer() {
|
||||
int i = this.mode.indexCount(this.vertices);
|
||||
int j = !this.indexOnly ? this.vertices * this.format.getVertexSize() : 0;
|
||||
VertexFormat.IndexType vertexformat$indextype = VertexFormat.IndexType.least(i);
|
||||
boolean flag;
|
||||
int k;
|
||||
if (this.sortingPoints != null) {
|
||||
int l = Mth.roundToward(i * vertexformat$indextype.bytes, 4);
|
||||
this.ensureCapacity(l);
|
||||
this.putSortedQuadIndices(vertexformat$indextype);
|
||||
flag = false;
|
||||
this.nextElementByte += l;
|
||||
k = j + l;
|
||||
} else {
|
||||
flag = true;
|
||||
k = j;
|
||||
}
|
||||
|
||||
int i1 = this.renderedBufferPointer;
|
||||
this.renderedBufferPointer += k;
|
||||
++this.renderedBufferCount;
|
||||
BufferBuilder.DrawState bufferbuilder$drawstate = new BufferBuilder.DrawState(this.format, this.vertices, i, this.mode, vertexformat$indextype, this.indexOnly, flag);
|
||||
return new BufferBuilder.RenderedBuffer(i1, bufferbuilder$drawstate);
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
this.building = false;
|
||||
this.vertices = 0;
|
||||
this.currentElement = null;
|
||||
this.elementIndex = 0;
|
||||
this.sortingPoints = null;
|
||||
this.sorting = null;
|
||||
this.indexOnly = false;
|
||||
}
|
||||
|
||||
public void putByte(int p_85686_, byte p_85687_) {
|
||||
this.buffer.put(this.nextElementByte + p_85686_, p_85687_);
|
||||
}
|
||||
|
||||
public void putShort(int p_85700_, short p_85701_) {
|
||||
this.buffer.putShort(this.nextElementByte + p_85700_, p_85701_);
|
||||
}
|
||||
|
||||
public void putFloat(int p_85689_, float p_85690_) {
|
||||
this.buffer.putFloat(this.nextElementByte + p_85689_, p_85690_);
|
||||
}
|
||||
|
||||
public void endVertex() {
|
||||
if (this.elementIndex != 0) {
|
||||
throw new IllegalStateException("Not filled all elements of the vertex");
|
||||
} else {
|
||||
++this.vertices;
|
||||
this.ensureVertexCapacity();
|
||||
if (this.mode == VertexFormat.Mode.LINES || this.mode == VertexFormat.Mode.LINE_STRIP) {
|
||||
int i = this.format.getVertexSize();
|
||||
this.buffer.put(this.nextElementByte, this.buffer, this.nextElementByte - i, i);
|
||||
this.nextElementByte += i;
|
||||
++this.vertices;
|
||||
this.ensureVertexCapacity();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void nextElement() {
|
||||
ImmutableList<VertexFormatElement> immutablelist = this.format.getElements();
|
||||
this.elementIndex = (this.elementIndex + 1) % immutablelist.size();
|
||||
this.nextElementByte += this.currentElement.getByteSize();
|
||||
VertexFormatElement vertexformatelement = immutablelist.get(this.elementIndex);
|
||||
this.currentElement = vertexformatelement;
|
||||
if (vertexformatelement.getUsage() == VertexFormatElement.Usage.PADDING) {
|
||||
this.nextElement();
|
||||
}
|
||||
|
||||
if (this.defaultColorSet && this.currentElement.getUsage() == VertexFormatElement.Usage.COLOR) {
|
||||
BufferVertexConsumer.super.color(this.defaultR, this.defaultG, this.defaultB, this.defaultA);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public VertexConsumer color(int p_85692_, int p_85693_, int p_85694_, int p_85695_) {
|
||||
if (this.defaultColorSet) {
|
||||
throw new IllegalStateException();
|
||||
} else {
|
||||
return BufferVertexConsumer.super.color(p_85692_, p_85693_, p_85694_, p_85695_);
|
||||
}
|
||||
}
|
||||
|
||||
public void vertex(float p_85671_, float p_85672_, float p_85673_, float p_85674_, float p_85675_, float p_85676_, float p_85677_, float p_85678_, float p_85679_, int p_85680_, int p_85681_, float p_85682_, float p_85683_, float p_85684_) {
|
||||
if (this.defaultColorSet) {
|
||||
throw new IllegalStateException();
|
||||
} else if (this.fastFormat) {
|
||||
this.putFloat(0, p_85671_);
|
||||
this.putFloat(4, p_85672_);
|
||||
this.putFloat(8, p_85673_);
|
||||
this.putByte(12, (byte)((int)(p_85674_ * 255.0F)));
|
||||
this.putByte(13, (byte)((int)(p_85675_ * 255.0F)));
|
||||
this.putByte(14, (byte)((int)(p_85676_ * 255.0F)));
|
||||
this.putByte(15, (byte)((int)(p_85677_ * 255.0F)));
|
||||
this.putFloat(16, p_85678_);
|
||||
this.putFloat(20, p_85679_);
|
||||
int i;
|
||||
if (this.fullFormat) {
|
||||
this.putShort(24, (short)(p_85680_ & '\uffff'));
|
||||
this.putShort(26, (short)(p_85680_ >> 16 & '\uffff'));
|
||||
i = 28;
|
||||
} else {
|
||||
i = 24;
|
||||
}
|
||||
|
||||
this.putShort(i + 0, (short)(p_85681_ & '\uffff'));
|
||||
this.putShort(i + 2, (short)(p_85681_ >> 16 & '\uffff'));
|
||||
this.putByte(i + 4, BufferVertexConsumer.normalIntValue(p_85682_));
|
||||
this.putByte(i + 5, BufferVertexConsumer.normalIntValue(p_85683_));
|
||||
this.putByte(i + 6, BufferVertexConsumer.normalIntValue(p_85684_));
|
||||
this.nextElementByte += i + 8;
|
||||
this.endVertex();
|
||||
} else {
|
||||
super.vertex(p_85671_, p_85672_, p_85673_, p_85674_, p_85675_, p_85676_, p_85677_, p_85678_, p_85679_, p_85680_, p_85681_, p_85682_, p_85683_, p_85684_);
|
||||
}
|
||||
}
|
||||
|
||||
void releaseRenderedBuffer() {
|
||||
if (this.renderedBufferCount > 0 && --this.renderedBufferCount == 0) {
|
||||
this.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
if (this.renderedBufferCount > 0) {
|
||||
LOGGER.warn("Clearing BufferBuilder with unused batches");
|
||||
}
|
||||
|
||||
this.discard();
|
||||
}
|
||||
|
||||
public void discard() {
|
||||
this.renderedBufferCount = 0;
|
||||
this.renderedBufferPointer = 0;
|
||||
this.nextElementByte = 0;
|
||||
}
|
||||
|
||||
public VertexFormatElement currentElement() {
|
||||
if (this.currentElement == null) {
|
||||
throw new IllegalStateException("BufferBuilder not started");
|
||||
} else {
|
||||
return this.currentElement;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean building() {
|
||||
return this.building;
|
||||
}
|
||||
|
||||
ByteBuffer bufferSlice(int p_231170_, int p_231171_) {
|
||||
return MemoryUtil.memSlice(this.buffer, p_231170_, p_231171_ - p_231170_);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static record DrawState(VertexFormat format, int vertexCount, int indexCount, VertexFormat.Mode mode, VertexFormat.IndexType indexType, boolean indexOnly, boolean sequentialIndex) {
|
||||
public int vertexBufferSize() {
|
||||
return this.vertexCount * this.format.getVertexSize();
|
||||
}
|
||||
|
||||
public int vertexBufferStart() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int vertexBufferEnd() {
|
||||
return this.vertexBufferSize();
|
||||
}
|
||||
|
||||
public int indexBufferStart() {
|
||||
return this.indexOnly ? 0 : this.vertexBufferEnd();
|
||||
}
|
||||
|
||||
public int indexBufferEnd() {
|
||||
return this.indexBufferStart() + this.indexBufferSize();
|
||||
}
|
||||
|
||||
private int indexBufferSize() {
|
||||
return this.sequentialIndex ? 0 : this.indexCount * this.indexType.bytes;
|
||||
}
|
||||
|
||||
public int bufferSize() {
|
||||
return this.indexBufferEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RenderedBuffer {
|
||||
private final int pointer;
|
||||
private final BufferBuilder.DrawState drawState;
|
||||
private boolean released;
|
||||
|
||||
RenderedBuffer(int p_231194_, BufferBuilder.DrawState p_231195_) {
|
||||
this.pointer = p_231194_;
|
||||
this.drawState = p_231195_;
|
||||
}
|
||||
|
||||
public ByteBuffer vertexBuffer() {
|
||||
int i = this.pointer + this.drawState.vertexBufferStart();
|
||||
int j = this.pointer + this.drawState.vertexBufferEnd();
|
||||
return BufferBuilder.this.bufferSlice(i, j);
|
||||
}
|
||||
|
||||
public ByteBuffer indexBuffer() {
|
||||
int i = this.pointer + this.drawState.indexBufferStart();
|
||||
int j = this.pointer + this.drawState.indexBufferEnd();
|
||||
return BufferBuilder.this.bufferSlice(i, j);
|
||||
}
|
||||
|
||||
public BufferBuilder.DrawState drawState() {
|
||||
return this.drawState;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.drawState.vertexCount == 0;
|
||||
}
|
||||
|
||||
public void release() {
|
||||
if (this.released) {
|
||||
throw new IllegalStateException("Buffer has already been released!");
|
||||
} else {
|
||||
BufferBuilder.this.releaseRenderedBuffer();
|
||||
this.released = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class SortState {
|
||||
final VertexFormat.Mode mode;
|
||||
final int vertices;
|
||||
@Nullable
|
||||
final Vector3f[] sortingPoints;
|
||||
@Nullable
|
||||
final VertexSorting sorting;
|
||||
|
||||
SortState(VertexFormat.Mode p_278011_, int p_277510_, @Nullable Vector3f[] p_278102_, @Nullable VertexSorting p_277855_) {
|
||||
this.mode = p_278011_;
|
||||
this.vertices = p_277510_;
|
||||
this.sortingPoints = p_278102_;
|
||||
this.sorting = p_277855_;
|
||||
}
|
||||
}
|
||||
|
||||
// Forge start
|
||||
public void putBulkData(ByteBuffer buffer) {
|
||||
ensureCapacity(buffer.limit() + this.format.getVertexSize());
|
||||
this.buffer.position(this.nextElementByte);
|
||||
this.buffer.put(buffer);
|
||||
this.buffer.position(0);
|
||||
this.vertices += buffer.limit() / this.format.getVertexSize();
|
||||
this.nextElementByte += buffer.limit();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.mojang.blaze3d.vertex;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class BufferUploader {
|
||||
@Nullable
|
||||
private static VertexBuffer lastImmediateBuffer;
|
||||
|
||||
public static void reset() {
|
||||
if (lastImmediateBuffer != null) {
|
||||
invalidate();
|
||||
VertexBuffer.unbind();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void invalidate() {
|
||||
lastImmediateBuffer = null;
|
||||
}
|
||||
|
||||
public static void drawWithShader(BufferBuilder.RenderedBuffer p_231203_) {
|
||||
if (!RenderSystem.isOnRenderThreadOrInit()) {
|
||||
RenderSystem.recordRenderCall(() -> {
|
||||
_drawWithShader(p_231203_);
|
||||
});
|
||||
} else {
|
||||
_drawWithShader(p_231203_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void _drawWithShader(BufferBuilder.RenderedBuffer p_231212_) {
|
||||
VertexBuffer vertexbuffer = upload(p_231212_);
|
||||
if (vertexbuffer != null) {
|
||||
vertexbuffer.drawWithShader(RenderSystem.getModelViewMatrix(), RenderSystem.getProjectionMatrix(), RenderSystem.getShader());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void draw(BufferBuilder.RenderedBuffer p_231210_) {
|
||||
VertexBuffer vertexbuffer = upload(p_231210_);
|
||||
if (vertexbuffer != null) {
|
||||
vertexbuffer.draw();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static VertexBuffer upload(BufferBuilder.RenderedBuffer p_231214_) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
if (p_231214_.isEmpty()) {
|
||||
p_231214_.release();
|
||||
return null;
|
||||
} else {
|
||||
VertexBuffer vertexbuffer = bindImmediateBuffer(p_231214_.drawState().format());
|
||||
vertexbuffer.upload(p_231214_);
|
||||
return vertexbuffer;
|
||||
}
|
||||
}
|
||||
|
||||
private static VertexBuffer bindImmediateBuffer(VertexFormat p_231207_) {
|
||||
VertexBuffer vertexbuffer = p_231207_.getImmediateDrawVertexBuffer();
|
||||
bindImmediateBuffer(vertexbuffer);
|
||||
return vertexbuffer;
|
||||
}
|
||||
|
||||
private static void bindImmediateBuffer(VertexBuffer p_231205_) {
|
||||
if (p_231205_ != lastImmediateBuffer) {
|
||||
p_231205_.bind();
|
||||
lastImmediateBuffer = p_231205_;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package com.mojang.blaze3d.vertex;
|
||||
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface BufferVertexConsumer extends VertexConsumer {
|
||||
VertexFormatElement currentElement();
|
||||
|
||||
void nextElement();
|
||||
|
||||
void putByte(int p_85779_, byte p_85780_);
|
||||
|
||||
void putShort(int p_85791_, short p_85792_);
|
||||
|
||||
void putFloat(int p_85781_, float p_85782_);
|
||||
|
||||
default VertexConsumer vertex(double p_85771_, double p_85772_, double p_85773_) {
|
||||
if (this.currentElement().getUsage() != VertexFormatElement.Usage.POSITION) {
|
||||
return this;
|
||||
} else if (this.currentElement().getType() == VertexFormatElement.Type.FLOAT && this.currentElement().getCount() == 3) {
|
||||
this.putFloat(0, (float)p_85771_);
|
||||
this.putFloat(4, (float)p_85772_);
|
||||
this.putFloat(8, (float)p_85773_);
|
||||
this.nextElement();
|
||||
return this;
|
||||
} else {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
default VertexConsumer color(int p_85787_, int p_85788_, int p_85789_, int p_85790_) {
|
||||
VertexFormatElement vertexformatelement = this.currentElement();
|
||||
if (vertexformatelement.getUsage() != VertexFormatElement.Usage.COLOR) {
|
||||
return this;
|
||||
} else if (vertexformatelement.getType() == VertexFormatElement.Type.UBYTE && vertexformatelement.getCount() == 4) {
|
||||
this.putByte(0, (byte)p_85787_);
|
||||
this.putByte(1, (byte)p_85788_);
|
||||
this.putByte(2, (byte)p_85789_);
|
||||
this.putByte(3, (byte)p_85790_);
|
||||
this.nextElement();
|
||||
return this;
|
||||
} else {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
default VertexConsumer uv(float p_85777_, float p_85778_) {
|
||||
VertexFormatElement vertexformatelement = this.currentElement();
|
||||
if (vertexformatelement.getUsage() == VertexFormatElement.Usage.UV && vertexformatelement.getIndex() == 0) {
|
||||
if (vertexformatelement.getType() == VertexFormatElement.Type.FLOAT && vertexformatelement.getCount() == 2) {
|
||||
this.putFloat(0, p_85777_);
|
||||
this.putFloat(4, p_85778_);
|
||||
this.nextElement();
|
||||
return this;
|
||||
} else {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
default VertexConsumer overlayCoords(int p_85784_, int p_85785_) {
|
||||
return this.uvShort((short)p_85784_, (short)p_85785_, 1);
|
||||
}
|
||||
|
||||
default VertexConsumer uv2(int p_85802_, int p_85803_) {
|
||||
return this.uvShort((short)p_85802_, (short)p_85803_, 2);
|
||||
}
|
||||
|
||||
default VertexConsumer uvShort(short p_85794_, short p_85795_, int p_85796_) {
|
||||
VertexFormatElement vertexformatelement = this.currentElement();
|
||||
if (vertexformatelement.getUsage() == VertexFormatElement.Usage.UV && vertexformatelement.getIndex() == p_85796_) {
|
||||
if (vertexformatelement.getType() == VertexFormatElement.Type.SHORT && vertexformatelement.getCount() == 2) {
|
||||
this.putShort(0, p_85794_);
|
||||
this.putShort(2, p_85795_);
|
||||
this.nextElement();
|
||||
return this;
|
||||
} else {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
default VertexConsumer normal(float p_85798_, float p_85799_, float p_85800_) {
|
||||
VertexFormatElement vertexformatelement = this.currentElement();
|
||||
if (vertexformatelement.getUsage() != VertexFormatElement.Usage.NORMAL) {
|
||||
return this;
|
||||
} else if (vertexformatelement.getType() == VertexFormatElement.Type.BYTE && vertexformatelement.getCount() == 3) {
|
||||
this.putByte(0, normalIntValue(p_85798_));
|
||||
this.putByte(1, normalIntValue(p_85799_));
|
||||
this.putByte(2, normalIntValue(p_85800_));
|
||||
this.nextElement();
|
||||
return this;
|
||||
} else {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
static byte normalIntValue(float p_85775_) {
|
||||
return (byte)((int)(Mth.clamp(p_85775_, -1.0F, 1.0F) * 127.0F) & 255);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.mojang.blaze3d.vertex;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class DefaultVertexFormat {
|
||||
public static final VertexFormatElement ELEMENT_POSITION = new VertexFormatElement(0, VertexFormatElement.Type.FLOAT, VertexFormatElement.Usage.POSITION, 3);
|
||||
public static final VertexFormatElement ELEMENT_COLOR = new VertexFormatElement(0, VertexFormatElement.Type.UBYTE, VertexFormatElement.Usage.COLOR, 4);
|
||||
public static final VertexFormatElement ELEMENT_UV0 = new VertexFormatElement(0, VertexFormatElement.Type.FLOAT, VertexFormatElement.Usage.UV, 2);
|
||||
public static final VertexFormatElement ELEMENT_UV1 = new VertexFormatElement(1, VertexFormatElement.Type.SHORT, VertexFormatElement.Usage.UV, 2);
|
||||
public static final VertexFormatElement ELEMENT_UV2 = new VertexFormatElement(2, VertexFormatElement.Type.SHORT, VertexFormatElement.Usage.UV, 2);
|
||||
public static final VertexFormatElement ELEMENT_NORMAL = new VertexFormatElement(0, VertexFormatElement.Type.BYTE, VertexFormatElement.Usage.NORMAL, 3);
|
||||
public static final VertexFormatElement ELEMENT_PADDING = new VertexFormatElement(0, VertexFormatElement.Type.BYTE, VertexFormatElement.Usage.PADDING, 1);
|
||||
public static final VertexFormatElement ELEMENT_UV = ELEMENT_UV0;
|
||||
public static final VertexFormat BLIT_SCREEN = new VertexFormat(ImmutableMap.<String, VertexFormatElement>builder().put("Position", ELEMENT_POSITION).put("UV", ELEMENT_UV).put("Color", ELEMENT_COLOR).build());
|
||||
public static final VertexFormat BLOCK = new VertexFormat(ImmutableMap.<String, VertexFormatElement>builder().put("Position", ELEMENT_POSITION).put("Color", ELEMENT_COLOR).put("UV0", ELEMENT_UV0).put("UV2", ELEMENT_UV2).put("Normal", ELEMENT_NORMAL).put("Padding", ELEMENT_PADDING).build());
|
||||
public static final VertexFormat NEW_ENTITY = new VertexFormat(ImmutableMap.<String, VertexFormatElement>builder().put("Position", ELEMENT_POSITION).put("Color", ELEMENT_COLOR).put("UV0", ELEMENT_UV0).put("UV1", ELEMENT_UV1).put("UV2", ELEMENT_UV2).put("Normal", ELEMENT_NORMAL).put("Padding", ELEMENT_PADDING).build());
|
||||
public static final VertexFormat PARTICLE = new VertexFormat(ImmutableMap.<String, VertexFormatElement>builder().put("Position", ELEMENT_POSITION).put("UV0", ELEMENT_UV0).put("Color", ELEMENT_COLOR).put("UV2", ELEMENT_UV2).build());
|
||||
public static final VertexFormat POSITION = new VertexFormat(ImmutableMap.<String, VertexFormatElement>builder().put("Position", ELEMENT_POSITION).build());
|
||||
public static final VertexFormat POSITION_COLOR = new VertexFormat(ImmutableMap.<String, VertexFormatElement>builder().put("Position", ELEMENT_POSITION).put("Color", ELEMENT_COLOR).build());
|
||||
public static final VertexFormat POSITION_COLOR_NORMAL = new VertexFormat(ImmutableMap.<String, VertexFormatElement>builder().put("Position", ELEMENT_POSITION).put("Color", ELEMENT_COLOR).put("Normal", ELEMENT_NORMAL).put("Padding", ELEMENT_PADDING).build());
|
||||
public static final VertexFormat POSITION_COLOR_LIGHTMAP = new VertexFormat(ImmutableMap.<String, VertexFormatElement>builder().put("Position", ELEMENT_POSITION).put("Color", ELEMENT_COLOR).put("UV2", ELEMENT_UV2).build());
|
||||
public static final VertexFormat POSITION_TEX = new VertexFormat(ImmutableMap.<String, VertexFormatElement>builder().put("Position", ELEMENT_POSITION).put("UV0", ELEMENT_UV0).build());
|
||||
public static final VertexFormat POSITION_COLOR_TEX = new VertexFormat(ImmutableMap.<String, VertexFormatElement>builder().put("Position", ELEMENT_POSITION).put("Color", ELEMENT_COLOR).put("UV0", ELEMENT_UV0).build());
|
||||
public static final VertexFormat POSITION_TEX_COLOR = new VertexFormat(ImmutableMap.<String, VertexFormatElement>builder().put("Position", ELEMENT_POSITION).put("UV0", ELEMENT_UV0).put("Color", ELEMENT_COLOR).build());
|
||||
public static final VertexFormat POSITION_COLOR_TEX_LIGHTMAP = new VertexFormat(ImmutableMap.<String, VertexFormatElement>builder().put("Position", ELEMENT_POSITION).put("Color", ELEMENT_COLOR).put("UV0", ELEMENT_UV0).put("UV2", ELEMENT_UV2).build());
|
||||
public static final VertexFormat POSITION_TEX_LIGHTMAP_COLOR = new VertexFormat(ImmutableMap.<String, VertexFormatElement>builder().put("Position", ELEMENT_POSITION).put("UV0", ELEMENT_UV0).put("UV2", ELEMENT_UV2).put("Color", ELEMENT_COLOR).build());
|
||||
public static final VertexFormat POSITION_TEX_COLOR_NORMAL = new VertexFormat(ImmutableMap.<String, VertexFormatElement>builder().put("Position", ELEMENT_POSITION).put("UV0", ELEMENT_UV0).put("Color", ELEMENT_COLOR).put("Normal", ELEMENT_NORMAL).put("Padding", ELEMENT_PADDING).build());
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.mojang.blaze3d.vertex;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public abstract class DefaultedVertexConsumer implements VertexConsumer {
|
||||
protected boolean defaultColorSet;
|
||||
protected int defaultR = 255;
|
||||
protected int defaultG = 255;
|
||||
protected int defaultB = 255;
|
||||
protected int defaultA = 255;
|
||||
|
||||
public void defaultColor(int p_85830_, int p_85831_, int p_85832_, int p_85833_) {
|
||||
this.defaultR = p_85830_;
|
||||
this.defaultG = p_85831_;
|
||||
this.defaultB = p_85832_;
|
||||
this.defaultA = p_85833_;
|
||||
this.defaultColorSet = true;
|
||||
}
|
||||
|
||||
public void unsetDefaultColor() {
|
||||
this.defaultColorSet = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.mojang.blaze3d.vertex;
|
||||
|
||||
import com.google.common.collect.Queues;
|
||||
import java.util.Deque;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.joml.Matrix3f;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Quaternionf;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class PoseStack implements net.minecraftforge.client.extensions.IForgePoseStack {
|
||||
private final Deque<PoseStack.Pose> poseStack = Util.make(Queues.newArrayDeque(), (p_85848_) -> {
|
||||
Matrix4f matrix4f = new Matrix4f();
|
||||
Matrix3f matrix3f = new Matrix3f();
|
||||
p_85848_.add(new PoseStack.Pose(matrix4f, matrix3f));
|
||||
});
|
||||
|
||||
public void translate(double p_85838_, double p_85839_, double p_85840_) {
|
||||
this.translate((float)p_85838_, (float)p_85839_, (float)p_85840_);
|
||||
}
|
||||
|
||||
public void translate(float p_254202_, float p_253782_, float p_254238_) {
|
||||
PoseStack.Pose posestack$pose = this.poseStack.getLast();
|
||||
posestack$pose.pose.translate(p_254202_, p_253782_, p_254238_);
|
||||
}
|
||||
|
||||
public void scale(float p_85842_, float p_85843_, float p_85844_) {
|
||||
PoseStack.Pose posestack$pose = this.poseStack.getLast();
|
||||
posestack$pose.pose.scale(p_85842_, p_85843_, p_85844_);
|
||||
if (p_85842_ == p_85843_ && p_85843_ == p_85844_) {
|
||||
if (p_85842_ > 0.0F) {
|
||||
return;
|
||||
}
|
||||
|
||||
posestack$pose.normal.scale(-1.0F);
|
||||
}
|
||||
|
||||
float f = 1.0F / p_85842_;
|
||||
float f1 = 1.0F / p_85843_;
|
||||
float f2 = 1.0F / p_85844_;
|
||||
float f3 = Mth.fastInvCubeRoot(f * f1 * f2);
|
||||
posestack$pose.normal.scale(f3 * f, f3 * f1, f3 * f2);
|
||||
}
|
||||
|
||||
public void mulPose(Quaternionf p_254385_) {
|
||||
PoseStack.Pose posestack$pose = this.poseStack.getLast();
|
||||
posestack$pose.pose.rotate(p_254385_);
|
||||
posestack$pose.normal.rotate(p_254385_);
|
||||
}
|
||||
|
||||
public void rotateAround(Quaternionf p_272904_, float p_273581_, float p_272655_, float p_273275_) {
|
||||
PoseStack.Pose posestack$pose = this.poseStack.getLast();
|
||||
posestack$pose.pose.rotateAround(p_272904_, p_273581_, p_272655_, p_273275_);
|
||||
posestack$pose.normal.rotate(p_272904_);
|
||||
}
|
||||
|
||||
public void pushPose() {
|
||||
PoseStack.Pose posestack$pose = this.poseStack.getLast();
|
||||
this.poseStack.addLast(new PoseStack.Pose(new Matrix4f(posestack$pose.pose), new Matrix3f(posestack$pose.normal)));
|
||||
}
|
||||
|
||||
public void popPose() {
|
||||
this.poseStack.removeLast();
|
||||
}
|
||||
|
||||
public PoseStack.Pose last() {
|
||||
return this.poseStack.getLast();
|
||||
}
|
||||
|
||||
public boolean clear() {
|
||||
return this.poseStack.size() == 1;
|
||||
}
|
||||
|
||||
public void setIdentity() {
|
||||
PoseStack.Pose posestack$pose = this.poseStack.getLast();
|
||||
posestack$pose.pose.identity();
|
||||
posestack$pose.normal.identity();
|
||||
}
|
||||
|
||||
public void mulPoseMatrix(Matrix4f p_254128_) {
|
||||
(this.poseStack.getLast()).pose.mul(p_254128_);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static final class Pose {
|
||||
final Matrix4f pose;
|
||||
final Matrix3f normal;
|
||||
|
||||
Pose(Matrix4f p_254509_, Matrix3f p_254348_) {
|
||||
this.pose = p_254509_;
|
||||
this.normal = p_254348_;
|
||||
}
|
||||
|
||||
public Matrix4f pose() {
|
||||
return this.pose;
|
||||
}
|
||||
|
||||
public Matrix3f normal() {
|
||||
return this.normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.mojang.blaze3d.vertex;
|
||||
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.joml.Matrix3f;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4f;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class SheetedDecalTextureGenerator extends DefaultedVertexConsumer {
|
||||
private final VertexConsumer delegate;
|
||||
private final Matrix4f cameraInversePose;
|
||||
private final Matrix3f normalInversePose;
|
||||
private final float textureScale;
|
||||
private float x;
|
||||
private float y;
|
||||
private float z;
|
||||
private int overlayU;
|
||||
private int overlayV;
|
||||
private int lightCoords;
|
||||
private float nx;
|
||||
private float ny;
|
||||
private float nz;
|
||||
|
||||
public SheetedDecalTextureGenerator(VertexConsumer p_260211_, Matrix4f p_259178_, Matrix3f p_259698_, float p_259312_) {
|
||||
this.delegate = p_260211_;
|
||||
this.cameraInversePose = (new Matrix4f(p_259178_)).invert();
|
||||
this.normalInversePose = (new Matrix3f(p_259698_)).invert();
|
||||
this.textureScale = p_259312_;
|
||||
this.resetState();
|
||||
}
|
||||
|
||||
private void resetState() {
|
||||
this.x = 0.0F;
|
||||
this.y = 0.0F;
|
||||
this.z = 0.0F;
|
||||
this.overlayU = 0;
|
||||
this.overlayV = 10;
|
||||
this.lightCoords = 15728880;
|
||||
this.nx = 0.0F;
|
||||
this.ny = 1.0F;
|
||||
this.nz = 0.0F;
|
||||
}
|
||||
|
||||
public void endVertex() {
|
||||
Vector3f vector3f = this.normalInversePose.transform(new Vector3f(this.nx, this.ny, this.nz));
|
||||
Direction direction = net.minecraftforge.client.ForgeHooksClient.getNearestStable(vector3f.x(), vector3f.y(), vector3f.z());
|
||||
Vector4f vector4f = this.cameraInversePose.transform(new Vector4f(this.x, this.y, this.z, 1.0F));
|
||||
vector4f.rotateY((float)Math.PI);
|
||||
vector4f.rotateX((-(float)Math.PI / 2F));
|
||||
vector4f.rotate(direction.getRotation());
|
||||
float f = -vector4f.x() * this.textureScale;
|
||||
float f1 = -vector4f.y() * this.textureScale;
|
||||
this.delegate.vertex((double)this.x, (double)this.y, (double)this.z).color(1.0F, 1.0F, 1.0F, 1.0F).uv(f, f1).overlayCoords(this.overlayU, this.overlayV).uv2(this.lightCoords).normal(this.nx, this.ny, this.nz).endVertex();
|
||||
this.resetState();
|
||||
}
|
||||
|
||||
public VertexConsumer vertex(double p_85885_, double p_85886_, double p_85887_) {
|
||||
this.x = (float)p_85885_;
|
||||
this.y = (float)p_85886_;
|
||||
this.z = (float)p_85887_;
|
||||
return this;
|
||||
}
|
||||
|
||||
public VertexConsumer color(int p_85895_, int p_85896_, int p_85897_, int p_85898_) {
|
||||
return this;
|
||||
}
|
||||
|
||||
public VertexConsumer uv(float p_85889_, float p_85890_) {
|
||||
return this;
|
||||
}
|
||||
|
||||
public VertexConsumer overlayCoords(int p_85892_, int p_85893_) {
|
||||
this.overlayU = p_85892_;
|
||||
this.overlayV = p_85893_;
|
||||
return this;
|
||||
}
|
||||
|
||||
public VertexConsumer uv2(int p_85904_, int p_85905_) {
|
||||
this.lightCoords = p_85904_ | p_85905_ << 16;
|
||||
return this;
|
||||
}
|
||||
|
||||
public VertexConsumer normal(float p_85900_, float p_85901_, float p_85902_) {
|
||||
this.nx = p_85900_;
|
||||
this.ny = p_85901_;
|
||||
this.nz = p_85902_;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.mojang.blaze3d.vertex;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class Tesselator {
|
||||
private static final int MAX_MEMORY_USE = 8388608;
|
||||
private static final int MAX_FLOATS = 2097152;
|
||||
private final BufferBuilder builder;
|
||||
private static final Tesselator INSTANCE = new Tesselator();
|
||||
|
||||
public static Tesselator getInstance() {
|
||||
RenderSystem.assertOnGameThreadOrInit();
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public Tesselator(int p_85912_) {
|
||||
this.builder = new BufferBuilder(p_85912_);
|
||||
}
|
||||
|
||||
public Tesselator() {
|
||||
this(2097152);
|
||||
}
|
||||
|
||||
public void end() {
|
||||
BufferUploader.drawWithShader(this.builder.end());
|
||||
}
|
||||
|
||||
public BufferBuilder getBuilder() {
|
||||
return this.builder;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
package com.mojang.blaze3d.vertex;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.platform.Window;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import java.nio.ByteBuffer;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.ShaderInstance;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.joml.Matrix4f;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class VertexBuffer implements AutoCloseable {
|
||||
private final VertexBuffer.Usage usage;
|
||||
private int vertexBufferId;
|
||||
private int indexBufferId;
|
||||
private int arrayObjectId;
|
||||
@Nullable
|
||||
private VertexFormat format;
|
||||
@Nullable
|
||||
private RenderSystem.AutoStorageIndexBuffer sequentialIndices;
|
||||
private VertexFormat.IndexType indexType;
|
||||
private int indexCount;
|
||||
private VertexFormat.Mode mode;
|
||||
|
||||
public VertexBuffer(VertexBuffer.Usage p_286252_) {
|
||||
this.usage = p_286252_;
|
||||
RenderSystem.assertOnRenderThread();
|
||||
this.vertexBufferId = GlStateManager._glGenBuffers();
|
||||
this.indexBufferId = GlStateManager._glGenBuffers();
|
||||
this.arrayObjectId = GlStateManager._glGenVertexArrays();
|
||||
}
|
||||
|
||||
public void upload(BufferBuilder.RenderedBuffer p_231222_) {
|
||||
if (!this.isInvalid()) {
|
||||
RenderSystem.assertOnRenderThread();
|
||||
|
||||
try {
|
||||
BufferBuilder.DrawState bufferbuilder$drawstate = p_231222_.drawState();
|
||||
this.format = this.uploadVertexBuffer(bufferbuilder$drawstate, p_231222_.vertexBuffer());
|
||||
this.sequentialIndices = this.uploadIndexBuffer(bufferbuilder$drawstate, p_231222_.indexBuffer());
|
||||
this.indexCount = bufferbuilder$drawstate.indexCount();
|
||||
this.indexType = bufferbuilder$drawstate.indexType();
|
||||
this.mode = bufferbuilder$drawstate.mode();
|
||||
} finally {
|
||||
p_231222_.release();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private VertexFormat uploadVertexBuffer(BufferBuilder.DrawState p_231219_, ByteBuffer p_231220_) {
|
||||
boolean flag = false;
|
||||
if (!p_231219_.format().equals(this.format)) {
|
||||
if (this.format != null) {
|
||||
this.format.clearBufferState();
|
||||
}
|
||||
|
||||
GlStateManager._glBindBuffer(34962, this.vertexBufferId);
|
||||
p_231219_.format().setupBufferState();
|
||||
flag = true;
|
||||
}
|
||||
|
||||
if (!p_231219_.indexOnly()) {
|
||||
if (!flag) {
|
||||
GlStateManager._glBindBuffer(34962, this.vertexBufferId);
|
||||
}
|
||||
|
||||
RenderSystem.glBufferData(34962, p_231220_, this.usage.id);
|
||||
}
|
||||
|
||||
return p_231219_.format();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private RenderSystem.AutoStorageIndexBuffer uploadIndexBuffer(BufferBuilder.DrawState p_231224_, ByteBuffer p_231225_) {
|
||||
if (!p_231224_.sequentialIndex()) {
|
||||
GlStateManager._glBindBuffer(34963, this.indexBufferId);
|
||||
RenderSystem.glBufferData(34963, p_231225_, this.usage.id);
|
||||
return null;
|
||||
} else {
|
||||
RenderSystem.AutoStorageIndexBuffer rendersystem$autostorageindexbuffer = RenderSystem.getSequentialBuffer(p_231224_.mode());
|
||||
if (rendersystem$autostorageindexbuffer != this.sequentialIndices || !rendersystem$autostorageindexbuffer.hasStorage(p_231224_.indexCount())) {
|
||||
rendersystem$autostorageindexbuffer.bind(p_231224_.indexCount());
|
||||
}
|
||||
|
||||
return rendersystem$autostorageindexbuffer;
|
||||
}
|
||||
}
|
||||
|
||||
public void bind() {
|
||||
BufferUploader.invalidate();
|
||||
GlStateManager._glBindVertexArray(this.arrayObjectId);
|
||||
}
|
||||
|
||||
public static void unbind() {
|
||||
BufferUploader.invalidate();
|
||||
GlStateManager._glBindVertexArray(0);
|
||||
}
|
||||
|
||||
public void draw() {
|
||||
RenderSystem.drawElements(this.mode.asGLMode, this.indexCount, this.getIndexType().asGLType);
|
||||
}
|
||||
|
||||
private VertexFormat.IndexType getIndexType() {
|
||||
RenderSystem.AutoStorageIndexBuffer rendersystem$autostorageindexbuffer = this.sequentialIndices;
|
||||
return rendersystem$autostorageindexbuffer != null ? rendersystem$autostorageindexbuffer.type() : this.indexType;
|
||||
}
|
||||
|
||||
public void drawWithShader(Matrix4f p_254480_, Matrix4f p_254555_, ShaderInstance p_253993_) {
|
||||
if (!RenderSystem.isOnRenderThread()) {
|
||||
RenderSystem.recordRenderCall(() -> {
|
||||
this._drawWithShader(new Matrix4f(p_254480_), new Matrix4f(p_254555_), p_253993_);
|
||||
});
|
||||
} else {
|
||||
this._drawWithShader(p_254480_, p_254555_, p_253993_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void _drawWithShader(Matrix4f p_253705_, Matrix4f p_253737_, ShaderInstance p_166879_) {
|
||||
for(int i = 0; i < 12; ++i) {
|
||||
int j = RenderSystem.getShaderTexture(i);
|
||||
p_166879_.setSampler("Sampler" + i, j);
|
||||
}
|
||||
|
||||
if (p_166879_.MODEL_VIEW_MATRIX != null) {
|
||||
p_166879_.MODEL_VIEW_MATRIX.set(p_253705_);
|
||||
}
|
||||
|
||||
if (p_166879_.PROJECTION_MATRIX != null) {
|
||||
p_166879_.PROJECTION_MATRIX.set(p_253737_);
|
||||
}
|
||||
|
||||
if (p_166879_.INVERSE_VIEW_ROTATION_MATRIX != null) {
|
||||
p_166879_.INVERSE_VIEW_ROTATION_MATRIX.set(RenderSystem.getInverseViewRotationMatrix());
|
||||
}
|
||||
|
||||
if (p_166879_.COLOR_MODULATOR != null) {
|
||||
p_166879_.COLOR_MODULATOR.set(RenderSystem.getShaderColor());
|
||||
}
|
||||
|
||||
if (p_166879_.GLINT_ALPHA != null) {
|
||||
p_166879_.GLINT_ALPHA.set(RenderSystem.getShaderGlintAlpha());
|
||||
}
|
||||
|
||||
if (p_166879_.FOG_START != null) {
|
||||
p_166879_.FOG_START.set(RenderSystem.getShaderFogStart());
|
||||
}
|
||||
|
||||
if (p_166879_.FOG_END != null) {
|
||||
p_166879_.FOG_END.set(RenderSystem.getShaderFogEnd());
|
||||
}
|
||||
|
||||
if (p_166879_.FOG_COLOR != null) {
|
||||
p_166879_.FOG_COLOR.set(RenderSystem.getShaderFogColor());
|
||||
}
|
||||
|
||||
if (p_166879_.FOG_SHAPE != null) {
|
||||
p_166879_.FOG_SHAPE.set(RenderSystem.getShaderFogShape().getIndex());
|
||||
}
|
||||
|
||||
if (p_166879_.TEXTURE_MATRIX != null) {
|
||||
p_166879_.TEXTURE_MATRIX.set(RenderSystem.getTextureMatrix());
|
||||
}
|
||||
|
||||
if (p_166879_.GAME_TIME != null) {
|
||||
p_166879_.GAME_TIME.set(RenderSystem.getShaderGameTime());
|
||||
}
|
||||
|
||||
if (p_166879_.SCREEN_SIZE != null) {
|
||||
Window window = Minecraft.getInstance().getWindow();
|
||||
p_166879_.SCREEN_SIZE.set((float)window.getWidth(), (float)window.getHeight());
|
||||
}
|
||||
|
||||
if (p_166879_.LINE_WIDTH != null && (this.mode == VertexFormat.Mode.LINES || this.mode == VertexFormat.Mode.LINE_STRIP)) {
|
||||
p_166879_.LINE_WIDTH.set(RenderSystem.getShaderLineWidth());
|
||||
}
|
||||
|
||||
RenderSystem.setupShaderLights(p_166879_);
|
||||
p_166879_.apply();
|
||||
this.draw();
|
||||
p_166879_.clear();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (this.vertexBufferId >= 0) {
|
||||
RenderSystem.glDeleteBuffers(this.vertexBufferId);
|
||||
this.vertexBufferId = -1;
|
||||
}
|
||||
|
||||
if (this.indexBufferId >= 0) {
|
||||
RenderSystem.glDeleteBuffers(this.indexBufferId);
|
||||
this.indexBufferId = -1;
|
||||
}
|
||||
|
||||
if (this.arrayObjectId >= 0) {
|
||||
RenderSystem.glDeleteVertexArrays(this.arrayObjectId);
|
||||
this.arrayObjectId = -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public VertexFormat getFormat() {
|
||||
return this.format;
|
||||
}
|
||||
|
||||
public boolean isInvalid() {
|
||||
return this.arrayObjectId == -1;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum Usage {
|
||||
STATIC(35044),
|
||||
DYNAMIC(35048);
|
||||
|
||||
final int id;
|
||||
|
||||
private Usage(int p_286680_) {
|
||||
this.id = p_286680_;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package com.mojang.blaze3d.vertex;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.util.FastColor;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.joml.Matrix3f;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4f;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface VertexConsumer extends net.minecraftforge.client.extensions.IForgeVertexConsumer {
|
||||
VertexConsumer vertex(double p_85945_, double p_85946_, double p_85947_);
|
||||
|
||||
VertexConsumer color(int p_85973_, int p_85974_, int p_85975_, int p_85976_);
|
||||
|
||||
VertexConsumer uv(float p_85948_, float p_85949_);
|
||||
|
||||
VertexConsumer overlayCoords(int p_85971_, int p_85972_);
|
||||
|
||||
VertexConsumer uv2(int p_86010_, int p_86011_);
|
||||
|
||||
VertexConsumer normal(float p_86005_, float p_86006_, float p_86007_);
|
||||
|
||||
void endVertex();
|
||||
|
||||
default void vertex(float p_85955_, float p_85956_, float p_85957_, float p_85958_, float p_85959_, float p_85960_, float p_85961_, float p_85962_, float p_85963_, int p_85964_, int p_85965_, float p_85966_, float p_85967_, float p_85968_) {
|
||||
this.vertex((double)p_85955_, (double)p_85956_, (double)p_85957_);
|
||||
this.color(p_85958_, p_85959_, p_85960_, p_85961_);
|
||||
this.uv(p_85962_, p_85963_);
|
||||
this.overlayCoords(p_85964_);
|
||||
this.uv2(p_85965_);
|
||||
this.normal(p_85966_, p_85967_, p_85968_);
|
||||
this.endVertex();
|
||||
}
|
||||
|
||||
void defaultColor(int p_166901_, int p_166902_, int p_166903_, int p_166904_);
|
||||
|
||||
void unsetDefaultColor();
|
||||
|
||||
default VertexConsumer color(float p_85951_, float p_85952_, float p_85953_, float p_85954_) {
|
||||
return this.color((int)(p_85951_ * 255.0F), (int)(p_85952_ * 255.0F), (int)(p_85953_ * 255.0F), (int)(p_85954_ * 255.0F));
|
||||
}
|
||||
|
||||
default VertexConsumer color(int p_193480_) {
|
||||
return this.color(FastColor.ARGB32.red(p_193480_), FastColor.ARGB32.green(p_193480_), FastColor.ARGB32.blue(p_193480_), FastColor.ARGB32.alpha(p_193480_));
|
||||
}
|
||||
|
||||
default VertexConsumer uv2(int p_85970_) {
|
||||
return this.uv2(p_85970_ & '\uffff', p_85970_ >> 16 & '\uffff');
|
||||
}
|
||||
|
||||
default VertexConsumer overlayCoords(int p_86009_) {
|
||||
return this.overlayCoords(p_86009_ & '\uffff', p_86009_ >> 16 & '\uffff');
|
||||
}
|
||||
|
||||
default void putBulkData(PoseStack.Pose p_85988_, BakedQuad p_85989_, float p_85990_, float p_85991_, float p_85992_, int p_85993_, int p_85994_) {
|
||||
this.putBulkData(p_85988_, p_85989_, new float[]{1.0F, 1.0F, 1.0F, 1.0F}, p_85990_, p_85991_, p_85992_, new int[]{p_85993_, p_85993_, p_85993_, p_85993_}, p_85994_, false);
|
||||
}
|
||||
|
||||
default void putBulkData(PoseStack.Pose p_85996_, BakedQuad p_85997_, float[] p_85998_, float p_85999_, float p_86000_, float p_86001_, int[] p_86002_, int p_86003_, boolean p_86004_) {
|
||||
putBulkData(p_85996_, p_85997_, p_85998_, p_85999_, p_86000_, p_86001_, 1, p_86002_, p_86003_, p_86004_);
|
||||
}
|
||||
|
||||
default void putBulkData(PoseStack.Pose p_85996_, BakedQuad p_85997_, float[] p_85998_, float p_85999_, float p_86000_, float p_86001_, float alpha, int[] p_86002_, int p_86003_, boolean p_86004_) {
|
||||
float[] afloat = new float[]{p_85998_[0], p_85998_[1], p_85998_[2], p_85998_[3]};
|
||||
int[] aint = new int[]{p_86002_[0], p_86002_[1], p_86002_[2], p_86002_[3]};
|
||||
int[] aint1 = p_85997_.getVertices();
|
||||
Vec3i vec3i = p_85997_.getDirection().getNormal();
|
||||
Matrix4f matrix4f = p_85996_.pose();
|
||||
Vector3f vector3f = p_85996_.normal().transform(new Vector3f((float)vec3i.getX(), (float)vec3i.getY(), (float)vec3i.getZ()));
|
||||
int i = 8;
|
||||
int j = aint1.length / 8;
|
||||
|
||||
try (MemoryStack memorystack = MemoryStack.stackPush()) {
|
||||
ByteBuffer bytebuffer = memorystack.malloc(DefaultVertexFormat.BLOCK.getVertexSize());
|
||||
IntBuffer intbuffer = bytebuffer.asIntBuffer();
|
||||
|
||||
for(int k = 0; k < j; ++k) {
|
||||
intbuffer.clear();
|
||||
intbuffer.put(aint1, k * 8, 8);
|
||||
float f = bytebuffer.getFloat(0);
|
||||
float f1 = bytebuffer.getFloat(4);
|
||||
float f2 = bytebuffer.getFloat(8);
|
||||
float f3;
|
||||
float f4;
|
||||
float f5;
|
||||
if (p_86004_) {
|
||||
float f6 = (float)(bytebuffer.get(12) & 255) / 255.0F;
|
||||
float f7 = (float)(bytebuffer.get(13) & 255) / 255.0F;
|
||||
float f8 = (float)(bytebuffer.get(14) & 255) / 255.0F;
|
||||
f3 = f6 * afloat[k] * p_85999_;
|
||||
f4 = f7 * afloat[k] * p_86000_;
|
||||
f5 = f8 * afloat[k] * p_86001_;
|
||||
} else {
|
||||
f3 = afloat[k] * p_85999_;
|
||||
f4 = afloat[k] * p_86000_;
|
||||
f5 = afloat[k] * p_86001_;
|
||||
}
|
||||
|
||||
int l = applyBakedLighting(p_86002_[k], bytebuffer);
|
||||
float f9 = bytebuffer.getFloat(16);
|
||||
float f10 = bytebuffer.getFloat(20);
|
||||
Vector4f vector4f = matrix4f.transform(new Vector4f(f, f1, f2, 1.0F));
|
||||
applyBakedNormals(vector3f, bytebuffer, p_85996_.normal());
|
||||
float vertexAlpha = p_86004_ ? alpha * (float) (bytebuffer.get(15) & 255) / 255.0F : alpha;
|
||||
this.vertex(vector4f.x(), vector4f.y(), vector4f.z(), f3, f4, f5, vertexAlpha, f9, f10, p_86003_, l, vector3f.x(), vector3f.y(), vector3f.z());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
default VertexConsumer vertex(Matrix4f p_254075_, float p_254519_, float p_253869_, float p_253980_) {
|
||||
Vector4f vector4f = p_254075_.transform(new Vector4f(p_254519_, p_253869_, p_253980_, 1.0F));
|
||||
return this.vertex((double)vector4f.x(), (double)vector4f.y(), (double)vector4f.z());
|
||||
}
|
||||
|
||||
default VertexConsumer normal(Matrix3f p_253747_, float p_254430_, float p_253877_, float p_254167_) {
|
||||
Vector3f vector3f = p_253747_.transform(new Vector3f(p_254430_, p_253877_, p_254167_));
|
||||
return this.normal(vector3f.x(), vector3f.y(), vector3f.z());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
package com.mojang.blaze3d.vertex;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class VertexFormat {
|
||||
private final ImmutableList<VertexFormatElement> elements;
|
||||
private final ImmutableMap<String, VertexFormatElement> elementMapping;
|
||||
private final IntList offsets = new IntArrayList();
|
||||
private final int vertexSize;
|
||||
@Nullable
|
||||
private VertexBuffer immediateDrawVertexBuffer;
|
||||
|
||||
public VertexFormat(ImmutableMap<String, VertexFormatElement> p_166910_) {
|
||||
this.elementMapping = p_166910_;
|
||||
this.elements = p_166910_.values().asList();
|
||||
int i = 0;
|
||||
|
||||
for(VertexFormatElement vertexformatelement : p_166910_.values()) {
|
||||
this.offsets.add(i);
|
||||
i += vertexformatelement.getByteSize();
|
||||
}
|
||||
|
||||
this.vertexSize = i;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "format: " + this.elementMapping.size() + " elements: " + (String)this.elementMapping.entrySet().stream().map(Object::toString).collect(Collectors.joining(" "));
|
||||
}
|
||||
|
||||
public int getIntegerSize() {
|
||||
return this.getVertexSize() / 4;
|
||||
}
|
||||
|
||||
public int getVertexSize() {
|
||||
return this.vertexSize;
|
||||
}
|
||||
|
||||
public ImmutableList<VertexFormatElement> getElements() {
|
||||
return this.elements;
|
||||
}
|
||||
|
||||
public ImmutableList<String> getElementAttributeNames() {
|
||||
return this.elementMapping.keySet().asList();
|
||||
}
|
||||
|
||||
public boolean equals(Object p_86026_) {
|
||||
if (this == p_86026_) {
|
||||
return true;
|
||||
} else if (p_86026_ != null && this.getClass() == p_86026_.getClass()) {
|
||||
VertexFormat vertexformat = (VertexFormat)p_86026_;
|
||||
return this.vertexSize != vertexformat.vertexSize ? false : this.elementMapping.equals(vertexformat.elementMapping);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.elementMapping.hashCode();
|
||||
}
|
||||
|
||||
public void setupBufferState() {
|
||||
if (!RenderSystem.isOnRenderThread()) {
|
||||
RenderSystem.recordRenderCall(this::_setupBufferState);
|
||||
} else {
|
||||
this._setupBufferState();
|
||||
}
|
||||
}
|
||||
|
||||
private void _setupBufferState() {
|
||||
int i = this.getVertexSize();
|
||||
List<VertexFormatElement> list = this.getElements();
|
||||
|
||||
for(int j = 0; j < list.size(); ++j) {
|
||||
list.get(j).setupBufferState(j, (long)this.offsets.getInt(j), i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void clearBufferState() {
|
||||
if (!RenderSystem.isOnRenderThread()) {
|
||||
RenderSystem.recordRenderCall(this::_clearBufferState);
|
||||
} else {
|
||||
this._clearBufferState();
|
||||
}
|
||||
}
|
||||
|
||||
private void _clearBufferState() {
|
||||
ImmutableList<VertexFormatElement> immutablelist = this.getElements();
|
||||
|
||||
for(int i = 0; i < immutablelist.size(); ++i) {
|
||||
VertexFormatElement vertexformatelement = immutablelist.get(i);
|
||||
vertexformatelement.clearBufferState(i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public VertexBuffer getImmediateDrawVertexBuffer() {
|
||||
VertexBuffer vertexbuffer = this.immediateDrawVertexBuffer;
|
||||
if (vertexbuffer == null) {
|
||||
this.immediateDrawVertexBuffer = vertexbuffer = new VertexBuffer(VertexBuffer.Usage.DYNAMIC);
|
||||
}
|
||||
|
||||
return vertexbuffer;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum IndexType {
|
||||
SHORT(5123, 2),
|
||||
INT(5125, 4);
|
||||
|
||||
public final int asGLType;
|
||||
public final int bytes;
|
||||
|
||||
private IndexType(int p_166930_, int p_166931_) {
|
||||
this.asGLType = p_166930_;
|
||||
this.bytes = p_166931_;
|
||||
}
|
||||
|
||||
public static VertexFormat.IndexType least(int p_166934_) {
|
||||
return (p_166934_ & -65536) != 0 ? INT : SHORT;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum Mode {
|
||||
LINES(4, 2, 2, false),
|
||||
LINE_STRIP(5, 2, 1, true),
|
||||
DEBUG_LINES(1, 2, 2, false),
|
||||
DEBUG_LINE_STRIP(3, 2, 1, true),
|
||||
TRIANGLES(4, 3, 3, false),
|
||||
TRIANGLE_STRIP(5, 3, 1, true),
|
||||
TRIANGLE_FAN(6, 3, 1, true),
|
||||
QUADS(4, 4, 4, false);
|
||||
|
||||
public final int asGLMode;
|
||||
public final int primitiveLength;
|
||||
public final int primitiveStride;
|
||||
public final boolean connectedPrimitives;
|
||||
|
||||
private Mode(int p_231238_, int p_231239_, int p_231240_, boolean p_231241_) {
|
||||
this.asGLMode = p_231238_;
|
||||
this.primitiveLength = p_231239_;
|
||||
this.primitiveStride = p_231240_;
|
||||
this.connectedPrimitives = p_231241_;
|
||||
}
|
||||
|
||||
public int indexCount(int p_166959_) {
|
||||
int i;
|
||||
switch (this) {
|
||||
case LINE_STRIP:
|
||||
case DEBUG_LINES:
|
||||
case DEBUG_LINE_STRIP:
|
||||
case TRIANGLES:
|
||||
case TRIANGLE_STRIP:
|
||||
case TRIANGLE_FAN:
|
||||
i = p_166959_;
|
||||
break;
|
||||
case LINES:
|
||||
case QUADS:
|
||||
i = p_166959_ / 4 * 6;
|
||||
break;
|
||||
default:
|
||||
i = 0;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
public ImmutableMap<String, VertexFormatElement> getElementMapping() { return elementMapping; }
|
||||
public int getOffset(int index) { return offsets.getInt(index); }
|
||||
public boolean hasPosition() { return elements.stream().anyMatch(e -> e.getUsage() == VertexFormatElement.Usage.POSITION); }
|
||||
public boolean hasNormal() { return elements.stream().anyMatch(e -> e.getUsage() == VertexFormatElement.Usage.NORMAL); }
|
||||
public boolean hasColor() { return elements.stream().anyMatch(e -> e.getUsage() == VertexFormatElement.Usage.COLOR); }
|
||||
public boolean hasUV(int which) { return elements.stream().anyMatch(e -> e.getUsage() == VertexFormatElement.Usage.UV && e.getIndex() == which); }
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
package com.mojang.blaze3d.vertex;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class VertexFormatElement {
|
||||
private final VertexFormatElement.Type type;
|
||||
private final VertexFormatElement.Usage usage;
|
||||
private final int index;
|
||||
private final int count;
|
||||
private final int byteSize;
|
||||
|
||||
public VertexFormatElement(int p_86037_, VertexFormatElement.Type p_86038_, VertexFormatElement.Usage p_86039_, int p_86040_) {
|
||||
if (this.supportsUsage(p_86037_, p_86039_)) {
|
||||
this.usage = p_86039_;
|
||||
this.type = p_86038_;
|
||||
this.index = p_86037_;
|
||||
this.count = p_86040_;
|
||||
this.byteSize = p_86038_.getSize() * this.count;
|
||||
} else {
|
||||
throw new IllegalStateException("Multiple vertex elements of the same type other than UVs are not supported");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean supportsUsage(int p_86043_, VertexFormatElement.Usage p_86044_) {
|
||||
return p_86043_ == 0 || p_86044_ == VertexFormatElement.Usage.UV;
|
||||
}
|
||||
|
||||
public final VertexFormatElement.Type getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public final VertexFormatElement.Usage getUsage() {
|
||||
return this.usage;
|
||||
}
|
||||
|
||||
public final int getCount() {
|
||||
return this.count;
|
||||
}
|
||||
|
||||
public final int getIndex() {
|
||||
return this.index;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.count + "," + this.usage.getName() + "," + this.type.getName();
|
||||
}
|
||||
|
||||
public final int getByteSize() {
|
||||
return this.byteSize;
|
||||
}
|
||||
|
||||
public final boolean isPosition() {
|
||||
return this.usage == VertexFormatElement.Usage.POSITION;
|
||||
}
|
||||
|
||||
public boolean equals(Object p_86053_) {
|
||||
if (this == p_86053_) {
|
||||
return true;
|
||||
} else if (p_86053_ != null && this.getClass() == p_86053_.getClass()) {
|
||||
VertexFormatElement vertexformatelement = (VertexFormatElement)p_86053_;
|
||||
if (this.count != vertexformatelement.count) {
|
||||
return false;
|
||||
} else if (this.index != vertexformatelement.index) {
|
||||
return false;
|
||||
} else if (this.type != vertexformatelement.type) {
|
||||
return false;
|
||||
} else {
|
||||
return this.usage == vertexformatelement.usage;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int i = this.type.hashCode();
|
||||
i = 31 * i + this.usage.hashCode();
|
||||
i = 31 * i + this.index;
|
||||
return 31 * i + this.count;
|
||||
}
|
||||
|
||||
public void setupBufferState(int p_166966_, long p_166967_, int p_166968_) {
|
||||
this.usage.setupBufferState(this.count, this.type.getGlType(), p_166968_, p_166967_, this.index, p_166966_);
|
||||
}
|
||||
|
||||
public void clearBufferState(int p_166964_) {
|
||||
this.usage.clearBufferState(this.index, p_166964_);
|
||||
}
|
||||
|
||||
public int getElementCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum Type {
|
||||
FLOAT(4, "Float", 5126),
|
||||
UBYTE(1, "Unsigned Byte", 5121),
|
||||
BYTE(1, "Byte", 5120),
|
||||
USHORT(2, "Unsigned Short", 5123),
|
||||
SHORT(2, "Short", 5122),
|
||||
UINT(4, "Unsigned Int", 5125),
|
||||
INT(4, "Int", 5124);
|
||||
|
||||
private final int size;
|
||||
private final String name;
|
||||
private final int glType;
|
||||
|
||||
private Type(int p_86071_, String p_86072_, int p_86073_) {
|
||||
this.size = p_86071_;
|
||||
this.name = p_86072_;
|
||||
this.glType = p_86073_;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public int getGlType() {
|
||||
return this.glType;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum Usage {
|
||||
POSITION("Position", (p_167043_, p_167044_, p_167045_, p_167046_, p_167047_, p_167048_) -> {
|
||||
GlStateManager._enableVertexAttribArray(p_167048_);
|
||||
GlStateManager._vertexAttribPointer(p_167048_, p_167043_, p_167044_, false, p_167045_, p_167046_);
|
||||
}, (p_167040_, p_167041_) -> {
|
||||
GlStateManager._disableVertexAttribArray(p_167041_);
|
||||
}),
|
||||
NORMAL("Normal", (p_167033_, p_167034_, p_167035_, p_167036_, p_167037_, p_167038_) -> {
|
||||
GlStateManager._enableVertexAttribArray(p_167038_);
|
||||
GlStateManager._vertexAttribPointer(p_167038_, p_167033_, p_167034_, true, p_167035_, p_167036_);
|
||||
}, (p_167030_, p_167031_) -> {
|
||||
GlStateManager._disableVertexAttribArray(p_167031_);
|
||||
}),
|
||||
COLOR("Vertex Color", (p_167023_, p_167024_, p_167025_, p_167026_, p_167027_, p_167028_) -> {
|
||||
GlStateManager._enableVertexAttribArray(p_167028_);
|
||||
GlStateManager._vertexAttribPointer(p_167028_, p_167023_, p_167024_, true, p_167025_, p_167026_);
|
||||
}, (p_167020_, p_167021_) -> {
|
||||
GlStateManager._disableVertexAttribArray(p_167021_);
|
||||
}),
|
||||
UV("UV", (p_167013_, p_167014_, p_167015_, p_167016_, p_167017_, p_167018_) -> {
|
||||
GlStateManager._enableVertexAttribArray(p_167018_);
|
||||
if (p_167014_ == 5126) {
|
||||
GlStateManager._vertexAttribPointer(p_167018_, p_167013_, p_167014_, false, p_167015_, p_167016_);
|
||||
} else {
|
||||
GlStateManager._vertexAttribIPointer(p_167018_, p_167013_, p_167014_, p_167015_, p_167016_);
|
||||
}
|
||||
|
||||
}, (p_167010_, p_167011_) -> {
|
||||
GlStateManager._disableVertexAttribArray(p_167011_);
|
||||
}),
|
||||
PADDING("Padding", (p_167003_, p_167004_, p_167005_, p_167006_, p_167007_, p_167008_) -> {
|
||||
}, (p_167000_, p_167001_) -> {
|
||||
}),
|
||||
GENERIC("Generic", (p_166993_, p_166994_, p_166995_, p_166996_, p_166997_, p_166998_) -> {
|
||||
GlStateManager._enableVertexAttribArray(p_166998_);
|
||||
GlStateManager._vertexAttribPointer(p_166998_, p_166993_, p_166994_, false, p_166995_, p_166996_);
|
||||
}, (p_166990_, p_166991_) -> {
|
||||
GlStateManager._disableVertexAttribArray(p_166991_);
|
||||
});
|
||||
|
||||
private final String name;
|
||||
private final VertexFormatElement.Usage.SetupState setupState;
|
||||
private final VertexFormatElement.Usage.ClearState clearState;
|
||||
|
||||
private Usage(String p_166975_, VertexFormatElement.Usage.SetupState p_166976_, VertexFormatElement.Usage.ClearState p_166977_) {
|
||||
this.name = p_166975_;
|
||||
this.setupState = p_166976_;
|
||||
this.clearState = p_166977_;
|
||||
}
|
||||
|
||||
void setupBufferState(int p_166982_, int p_166983_, int p_166984_, long p_166985_, int p_166986_, int p_166987_) {
|
||||
this.setupState.setupBufferState(p_166982_, p_166983_, p_166984_, p_166985_, p_166986_, p_166987_);
|
||||
}
|
||||
|
||||
public void clearBufferState(int p_166979_, int p_166980_) {
|
||||
this.clearState.clearBufferState(p_166979_, p_166980_);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
interface ClearState {
|
||||
void clearBufferState(int p_167050_, int p_167051_);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
interface SetupState {
|
||||
void setupBufferState(int p_167053_, int p_167054_, int p_167055_, long p_167056_, int p_167057_, int p_167058_);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
package com.mojang.blaze3d.vertex;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class VertexMultiConsumer {
|
||||
public static VertexConsumer create() {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
public static VertexConsumer create(VertexConsumer p_167062_) {
|
||||
return p_167062_;
|
||||
}
|
||||
|
||||
public static VertexConsumer create(VertexConsumer p_86169_, VertexConsumer p_86170_) {
|
||||
return new VertexMultiConsumer.Double(p_86169_, p_86170_);
|
||||
}
|
||||
|
||||
public static VertexConsumer create(VertexConsumer... p_167064_) {
|
||||
return new VertexMultiConsumer.Multiple(p_167064_);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class Double implements VertexConsumer {
|
||||
private final VertexConsumer first;
|
||||
private final VertexConsumer second;
|
||||
|
||||
public Double(VertexConsumer p_86174_, VertexConsumer p_86175_) {
|
||||
if (p_86174_ == p_86175_) {
|
||||
throw new IllegalArgumentException("Duplicate delegates");
|
||||
} else {
|
||||
this.first = p_86174_;
|
||||
this.second = p_86175_;
|
||||
}
|
||||
}
|
||||
|
||||
public VertexConsumer vertex(double p_86177_, double p_86178_, double p_86179_) {
|
||||
this.first.vertex(p_86177_, p_86178_, p_86179_);
|
||||
this.second.vertex(p_86177_, p_86178_, p_86179_);
|
||||
return this;
|
||||
}
|
||||
|
||||
public VertexConsumer color(int p_86202_, int p_86203_, int p_86204_, int p_86205_) {
|
||||
this.first.color(p_86202_, p_86203_, p_86204_, p_86205_);
|
||||
this.second.color(p_86202_, p_86203_, p_86204_, p_86205_);
|
||||
return this;
|
||||
}
|
||||
|
||||
public VertexConsumer uv(float p_86181_, float p_86182_) {
|
||||
this.first.uv(p_86181_, p_86182_);
|
||||
this.second.uv(p_86181_, p_86182_);
|
||||
return this;
|
||||
}
|
||||
|
||||
public VertexConsumer overlayCoords(int p_86199_, int p_86200_) {
|
||||
this.first.overlayCoords(p_86199_, p_86200_);
|
||||
this.second.overlayCoords(p_86199_, p_86200_);
|
||||
return this;
|
||||
}
|
||||
|
||||
public VertexConsumer uv2(int p_86211_, int p_86212_) {
|
||||
this.first.uv2(p_86211_, p_86212_);
|
||||
this.second.uv2(p_86211_, p_86212_);
|
||||
return this;
|
||||
}
|
||||
|
||||
public VertexConsumer normal(float p_86207_, float p_86208_, float p_86209_) {
|
||||
this.first.normal(p_86207_, p_86208_, p_86209_);
|
||||
this.second.normal(p_86207_, p_86208_, p_86209_);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void vertex(float p_86184_, float p_86185_, float p_86186_, float p_86187_, float p_86188_, float p_86189_, float p_86190_, float p_86191_, float p_86192_, int p_86193_, int p_86194_, float p_86195_, float p_86196_, float p_86197_) {
|
||||
this.first.vertex(p_86184_, p_86185_, p_86186_, p_86187_, p_86188_, p_86189_, p_86190_, p_86191_, p_86192_, p_86193_, p_86194_, p_86195_, p_86196_, p_86197_);
|
||||
this.second.vertex(p_86184_, p_86185_, p_86186_, p_86187_, p_86188_, p_86189_, p_86190_, p_86191_, p_86192_, p_86193_, p_86194_, p_86195_, p_86196_, p_86197_);
|
||||
}
|
||||
|
||||
public void endVertex() {
|
||||
this.first.endVertex();
|
||||
this.second.endVertex();
|
||||
}
|
||||
|
||||
public void defaultColor(int p_167066_, int p_167067_, int p_167068_, int p_167069_) {
|
||||
this.first.defaultColor(p_167066_, p_167067_, p_167068_, p_167069_);
|
||||
this.second.defaultColor(p_167066_, p_167067_, p_167068_, p_167069_);
|
||||
}
|
||||
|
||||
public void unsetDefaultColor() {
|
||||
this.first.unsetDefaultColor();
|
||||
this.second.unsetDefaultColor();
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class Multiple implements VertexConsumer {
|
||||
private final VertexConsumer[] delegates;
|
||||
|
||||
public Multiple(VertexConsumer[] p_167073_) {
|
||||
for(int i = 0; i < p_167073_.length; ++i) {
|
||||
for(int j = i + 1; j < p_167073_.length; ++j) {
|
||||
if (p_167073_[i] == p_167073_[j]) {
|
||||
throw new IllegalArgumentException("Duplicate delegates");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.delegates = p_167073_;
|
||||
}
|
||||
|
||||
private void forEach(Consumer<VertexConsumer> p_167145_) {
|
||||
for(VertexConsumer vertexconsumer : this.delegates) {
|
||||
p_167145_.accept(vertexconsumer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public VertexConsumer vertex(double p_167075_, double p_167076_, double p_167077_) {
|
||||
this.forEach((p_167082_) -> {
|
||||
p_167082_.vertex(p_167075_, p_167076_, p_167077_);
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
public VertexConsumer color(int p_167130_, int p_167131_, int p_167132_, int p_167133_) {
|
||||
this.forEach((p_167163_) -> {
|
||||
p_167163_.color(p_167130_, p_167131_, p_167132_, p_167133_);
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
public VertexConsumer uv(float p_167084_, float p_167085_) {
|
||||
this.forEach((p_167125_) -> {
|
||||
p_167125_.uv(p_167084_, p_167085_);
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
public VertexConsumer overlayCoords(int p_167127_, int p_167128_) {
|
||||
this.forEach((p_167167_) -> {
|
||||
p_167167_.overlayCoords(p_167127_, p_167128_);
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
public VertexConsumer uv2(int p_167151_, int p_167152_) {
|
||||
this.forEach((p_167143_) -> {
|
||||
p_167143_.uv2(p_167151_, p_167152_);
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
public VertexConsumer normal(float p_167147_, float p_167148_, float p_167149_) {
|
||||
this.forEach((p_167121_) -> {
|
||||
p_167121_.normal(p_167147_, p_167148_, p_167149_);
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
public void vertex(float p_167087_, float p_167088_, float p_167089_, float p_167090_, float p_167091_, float p_167092_, float p_167093_, float p_167094_, float p_167095_, int p_167096_, int p_167097_, float p_167098_, float p_167099_, float p_167100_) {
|
||||
this.forEach((p_167116_) -> {
|
||||
p_167116_.vertex(p_167087_, p_167088_, p_167089_, p_167090_, p_167091_, p_167092_, p_167093_, p_167094_, p_167095_, p_167096_, p_167097_, p_167098_, p_167099_, p_167100_);
|
||||
});
|
||||
}
|
||||
|
||||
public void endVertex() {
|
||||
this.forEach(VertexConsumer::endVertex);
|
||||
}
|
||||
|
||||
public void defaultColor(int p_167154_, int p_167155_, int p_167156_, int p_167157_) {
|
||||
this.forEach((p_167139_) -> {
|
||||
p_167139_.defaultColor(p_167154_, p_167155_, p_167156_, p_167157_);
|
||||
});
|
||||
}
|
||||
|
||||
public void unsetDefaultColor() {
|
||||
this.forEach(VertexConsumer::unsetDefaultColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.mojang.blaze3d.vertex;
|
||||
|
||||
import com.google.common.primitives.Floats;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrays;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface VertexSorting {
|
||||
VertexSorting DISTANCE_TO_ORIGIN = byDistance(0.0F, 0.0F, 0.0F);
|
||||
VertexSorting ORTHOGRAPHIC_Z = byDistance((p_277433_) -> {
|
||||
return -p_277433_.z();
|
||||
});
|
||||
|
||||
static VertexSorting byDistance(float p_277642_, float p_277654_, float p_278092_) {
|
||||
return byDistance(new Vector3f(p_277642_, p_277654_, p_278092_));
|
||||
}
|
||||
|
||||
static VertexSorting byDistance(Vector3f p_277725_) {
|
||||
return byDistance(p_277725_::distanceSquared);
|
||||
}
|
||||
|
||||
static VertexSorting byDistance(VertexSorting.DistanceFunction p_277530_) {
|
||||
return (p_278083_) -> {
|
||||
float[] afloat = new float[p_278083_.length];
|
||||
int[] aint = new int[p_278083_.length];
|
||||
|
||||
for(int i = 0; i < p_278083_.length; aint[i] = i++) {
|
||||
afloat[i] = p_277530_.apply(p_278083_[i]);
|
||||
}
|
||||
|
||||
IntArrays.mergeSort(aint, (p_277443_, p_277864_) -> {
|
||||
return Floats.compare(afloat[p_277864_], afloat[p_277443_]);
|
||||
});
|
||||
return aint;
|
||||
};
|
||||
}
|
||||
|
||||
int[] sort(Vector3f[] p_277527_);
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface DistanceFunction {
|
||||
float apply(Vector3f p_277761_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
package com.mojang.blaze3d.vertex;
|
||||
|
||||
import com.mojang.blaze3d.FieldsAreNonnullByDefault;
|
||||
import com.mojang.blaze3d.MethodsReturnNonnullByDefault;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.mojang.math;
|
||||
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Axis {
|
||||
Axis XN = (p_254437_) -> {
|
||||
return (new Quaternionf()).rotationX(-p_254437_);
|
||||
};
|
||||
Axis XP = (p_254466_) -> {
|
||||
return (new Quaternionf()).rotationX(p_254466_);
|
||||
};
|
||||
Axis YN = (p_254442_) -> {
|
||||
return (new Quaternionf()).rotationY(-p_254442_);
|
||||
};
|
||||
Axis YP = (p_254103_) -> {
|
||||
return (new Quaternionf()).rotationY(p_254103_);
|
||||
};
|
||||
Axis ZN = (p_254110_) -> {
|
||||
return (new Quaternionf()).rotationZ(-p_254110_);
|
||||
};
|
||||
Axis ZP = (p_253997_) -> {
|
||||
return (new Quaternionf()).rotationZ(p_253997_);
|
||||
};
|
||||
|
||||
static Axis of(Vector3f p_254398_) {
|
||||
return (p_254401_) -> {
|
||||
return (new Quaternionf()).rotationAxis(p_254401_, p_254398_);
|
||||
};
|
||||
}
|
||||
|
||||
Quaternionf rotation(float p_254545_);
|
||||
|
||||
default Quaternionf rotationDegrees(float p_253800_) {
|
||||
return this.rotation(p_253800_ * ((float)Math.PI / 180F));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.mojang.math;
|
||||
|
||||
public class Constants {
|
||||
public static final float PI = (float)Math.PI;
|
||||
public static final float RAD_TO_DEG = (180F / (float)Math.PI);
|
||||
public static final float DEG_TO_RAD = ((float)Math.PI / 180F);
|
||||
public static final float EPSILON = 1.0E-6F;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.mojang.math;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import it.unimi.dsi.fastutil.ints.IntIterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public class Divisor implements IntIterator {
|
||||
private final int denominator;
|
||||
private final int quotient;
|
||||
private final int mod;
|
||||
private int returnedParts;
|
||||
private int remainder;
|
||||
|
||||
public Divisor(int p_254018_, int p_254504_) {
|
||||
this.denominator = p_254504_;
|
||||
if (p_254504_ > 0) {
|
||||
this.quotient = p_254018_ / p_254504_;
|
||||
this.mod = p_254018_ % p_254504_;
|
||||
} else {
|
||||
this.quotient = 0;
|
||||
this.mod = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return this.returnedParts < this.denominator;
|
||||
}
|
||||
|
||||
public int nextInt() {
|
||||
if (!this.hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
} else {
|
||||
int i = this.quotient;
|
||||
this.remainder += this.mod;
|
||||
if (this.remainder >= this.denominator) {
|
||||
this.remainder -= this.denominator;
|
||||
++i;
|
||||
}
|
||||
|
||||
++this.returnedParts;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public static Iterable<Integer> asIterable(int p_254381_, int p_254129_) {
|
||||
return () -> {
|
||||
return new Divisor(p_254381_, p_254129_);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.mojang.math;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.meta.TypeQualifierDefault;
|
||||
|
||||
@Nonnull
|
||||
@TypeQualifierDefault({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface FieldsAreNonnullByDefault {
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.mojang.math;
|
||||
|
||||
import org.joml.Math;
|
||||
import org.joml.Matrix3f;
|
||||
import org.joml.Quaternionf;
|
||||
|
||||
public record GivensParameters(float sinHalf, float cosHalf) {
|
||||
public static GivensParameters fromUnnormalized(float p_276277_, float p_276305_) {
|
||||
float f = Math.invsqrt(p_276277_ * p_276277_ + p_276305_ * p_276305_);
|
||||
return new GivensParameters(f * p_276277_, f * p_276305_);
|
||||
}
|
||||
|
||||
public static GivensParameters fromPositiveAngle(float p_276260_) {
|
||||
float f = Math.sin(p_276260_ / 2.0F);
|
||||
float f1 = Math.cosFromSin(f, p_276260_ / 2.0F);
|
||||
return new GivensParameters(f, f1);
|
||||
}
|
||||
|
||||
public GivensParameters inverse() {
|
||||
return new GivensParameters(-this.sinHalf, this.cosHalf);
|
||||
}
|
||||
|
||||
public Quaternionf aroundX(Quaternionf p_276271_) {
|
||||
return p_276271_.set(this.sinHalf, 0.0F, 0.0F, this.cosHalf);
|
||||
}
|
||||
|
||||
public Quaternionf aroundY(Quaternionf p_276323_) {
|
||||
return p_276323_.set(0.0F, this.sinHalf, 0.0F, this.cosHalf);
|
||||
}
|
||||
|
||||
public Quaternionf aroundZ(Quaternionf p_276281_) {
|
||||
return p_276281_.set(0.0F, 0.0F, this.sinHalf, this.cosHalf);
|
||||
}
|
||||
|
||||
public float cos() {
|
||||
return this.cosHalf * this.cosHalf - this.sinHalf * this.sinHalf;
|
||||
}
|
||||
|
||||
public float sin() {
|
||||
return 2.0F * this.sinHalf * this.cosHalf;
|
||||
}
|
||||
|
||||
public Matrix3f aroundX(Matrix3f p_276268_) {
|
||||
p_276268_.m01 = 0.0F;
|
||||
p_276268_.m02 = 0.0F;
|
||||
p_276268_.m10 = 0.0F;
|
||||
p_276268_.m20 = 0.0F;
|
||||
float f = this.cos();
|
||||
float f1 = this.sin();
|
||||
p_276268_.m11 = f;
|
||||
p_276268_.m22 = f;
|
||||
p_276268_.m12 = f1;
|
||||
p_276268_.m21 = -f1;
|
||||
p_276268_.m00 = 1.0F;
|
||||
return p_276268_;
|
||||
}
|
||||
|
||||
public Matrix3f aroundY(Matrix3f p_276274_) {
|
||||
p_276274_.m01 = 0.0F;
|
||||
p_276274_.m10 = 0.0F;
|
||||
p_276274_.m12 = 0.0F;
|
||||
p_276274_.m21 = 0.0F;
|
||||
float f = this.cos();
|
||||
float f1 = this.sin();
|
||||
p_276274_.m00 = f;
|
||||
p_276274_.m22 = f;
|
||||
p_276274_.m02 = -f1;
|
||||
p_276274_.m20 = f1;
|
||||
p_276274_.m11 = 1.0F;
|
||||
return p_276274_;
|
||||
}
|
||||
|
||||
public Matrix3f aroundZ(Matrix3f p_276317_) {
|
||||
p_276317_.m02 = 0.0F;
|
||||
p_276317_.m12 = 0.0F;
|
||||
p_276317_.m20 = 0.0F;
|
||||
p_276317_.m21 = 0.0F;
|
||||
float f = this.cos();
|
||||
float f1 = this.sin();
|
||||
p_276317_.m00 = f;
|
||||
p_276317_.m11 = f;
|
||||
p_276317_.m01 = f1;
|
||||
p_276317_.m10 = -f1;
|
||||
p_276317_.m22 = 1.0F;
|
||||
return p_276317_;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package com.mojang.math;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Triple;
|
||||
import org.joml.Math;
|
||||
import org.joml.Matrix3f;
|
||||
import org.joml.Matrix3fc;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
public class MatrixUtil {
|
||||
private static final float G = 3.0F + 2.0F * Math.sqrt(2.0F);
|
||||
private static final GivensParameters PI_4 = GivensParameters.fromPositiveAngle(((float)java.lang.Math.PI / 4F));
|
||||
|
||||
private MatrixUtil() {
|
||||
}
|
||||
|
||||
public static Matrix4f mulComponentWise(Matrix4f p_254173_, float p_253864_) {
|
||||
return p_254173_.set(p_254173_.m00() * p_253864_, p_254173_.m01() * p_253864_, p_254173_.m02() * p_253864_, p_254173_.m03() * p_253864_, p_254173_.m10() * p_253864_, p_254173_.m11() * p_253864_, p_254173_.m12() * p_253864_, p_254173_.m13() * p_253864_, p_254173_.m20() * p_253864_, p_254173_.m21() * p_253864_, p_254173_.m22() * p_253864_, p_254173_.m23() * p_253864_, p_254173_.m30() * p_253864_, p_254173_.m31() * p_253864_, p_254173_.m32() * p_253864_, p_254173_.m33() * p_253864_);
|
||||
}
|
||||
|
||||
private static GivensParameters approxGivensQuat(float p_276275_, float p_276276_, float p_276282_) {
|
||||
float f = 2.0F * (p_276275_ - p_276282_);
|
||||
return G * p_276276_ * p_276276_ < f * f ? GivensParameters.fromUnnormalized(p_276276_, f) : PI_4;
|
||||
}
|
||||
|
||||
private static GivensParameters qrGivensQuat(float p_253897_, float p_254413_) {
|
||||
float f = (float)java.lang.Math.hypot((double)p_253897_, (double)p_254413_);
|
||||
float f1 = f > 1.0E-6F ? p_254413_ : 0.0F;
|
||||
float f2 = Math.abs(p_253897_) + Math.max(f, 1.0E-6F);
|
||||
if (p_253897_ < 0.0F) {
|
||||
float f3 = f1;
|
||||
f1 = f2;
|
||||
f2 = f3;
|
||||
}
|
||||
|
||||
return GivensParameters.fromUnnormalized(f1, f2);
|
||||
}
|
||||
|
||||
private static void similarityTransform(Matrix3f p_276319_, Matrix3f p_276263_) {
|
||||
p_276319_.mul(p_276263_);
|
||||
p_276263_.transpose();
|
||||
p_276263_.mul(p_276319_);
|
||||
p_276319_.set((Matrix3fc)p_276263_);
|
||||
}
|
||||
|
||||
private static void stepJacobi(Matrix3f p_276262_, Matrix3f p_276279_, Quaternionf p_276314_, Quaternionf p_276299_) {
|
||||
if (p_276262_.m01 * p_276262_.m01 + p_276262_.m10 * p_276262_.m10 > 1.0E-6F) {
|
||||
GivensParameters givensparameters = approxGivensQuat(p_276262_.m00, 0.5F * (p_276262_.m01 + p_276262_.m10), p_276262_.m11);
|
||||
Quaternionf quaternionf = givensparameters.aroundZ(p_276314_);
|
||||
p_276299_.mul(quaternionf);
|
||||
givensparameters.aroundZ(p_276279_);
|
||||
similarityTransform(p_276262_, p_276279_);
|
||||
}
|
||||
|
||||
if (p_276262_.m02 * p_276262_.m02 + p_276262_.m20 * p_276262_.m20 > 1.0E-6F) {
|
||||
GivensParameters givensparameters1 = approxGivensQuat(p_276262_.m00, 0.5F * (p_276262_.m02 + p_276262_.m20), p_276262_.m22).inverse();
|
||||
Quaternionf quaternionf1 = givensparameters1.aroundY(p_276314_);
|
||||
p_276299_.mul(quaternionf1);
|
||||
givensparameters1.aroundY(p_276279_);
|
||||
similarityTransform(p_276262_, p_276279_);
|
||||
}
|
||||
|
||||
if (p_276262_.m12 * p_276262_.m12 + p_276262_.m21 * p_276262_.m21 > 1.0E-6F) {
|
||||
GivensParameters givensparameters2 = approxGivensQuat(p_276262_.m11, 0.5F * (p_276262_.m12 + p_276262_.m21), p_276262_.m22);
|
||||
Quaternionf quaternionf2 = givensparameters2.aroundX(p_276314_);
|
||||
p_276299_.mul(quaternionf2);
|
||||
givensparameters2.aroundX(p_276279_);
|
||||
similarityTransform(p_276262_, p_276279_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Quaternionf eigenvalueJacobi(Matrix3f p_276278_, int p_276269_) {
|
||||
Quaternionf quaternionf = new Quaternionf();
|
||||
Matrix3f matrix3f = new Matrix3f();
|
||||
Quaternionf quaternionf1 = new Quaternionf();
|
||||
|
||||
for(int i = 0; i < p_276269_; ++i) {
|
||||
stepJacobi(p_276278_, matrix3f, quaternionf1, quaternionf);
|
||||
}
|
||||
|
||||
quaternionf.normalize();
|
||||
return quaternionf;
|
||||
}
|
||||
|
||||
public static Triple<Quaternionf, Vector3f, Quaternionf> svdDecompose(Matrix3f p_253947_) {
|
||||
Matrix3f matrix3f = new Matrix3f(p_253947_);
|
||||
matrix3f.transpose();
|
||||
matrix3f.mul(p_253947_);
|
||||
Quaternionf quaternionf = eigenvalueJacobi(matrix3f, 5);
|
||||
float f = matrix3f.m00;
|
||||
float f1 = matrix3f.m11;
|
||||
boolean flag = (double)f < 1.0E-6D;
|
||||
boolean flag1 = (double)f1 < 1.0E-6D;
|
||||
Matrix3f matrix3f1 = p_253947_.rotate(quaternionf);
|
||||
Quaternionf quaternionf1 = new Quaternionf();
|
||||
Quaternionf quaternionf2 = new Quaternionf();
|
||||
GivensParameters givensparameters;
|
||||
if (flag) {
|
||||
givensparameters = qrGivensQuat(matrix3f1.m11, -matrix3f1.m10);
|
||||
} else {
|
||||
givensparameters = qrGivensQuat(matrix3f1.m00, matrix3f1.m01);
|
||||
}
|
||||
|
||||
Quaternionf quaternionf3 = givensparameters.aroundZ(quaternionf2);
|
||||
Matrix3f matrix3f2 = givensparameters.aroundZ(matrix3f);
|
||||
quaternionf1.mul(quaternionf3);
|
||||
matrix3f2.transpose().mul(matrix3f1);
|
||||
if (flag) {
|
||||
givensparameters = qrGivensQuat(matrix3f2.m22, -matrix3f2.m20);
|
||||
} else {
|
||||
givensparameters = qrGivensQuat(matrix3f2.m00, matrix3f2.m02);
|
||||
}
|
||||
|
||||
givensparameters = givensparameters.inverse();
|
||||
Quaternionf quaternionf4 = givensparameters.aroundY(quaternionf2);
|
||||
Matrix3f matrix3f3 = givensparameters.aroundY(matrix3f1);
|
||||
quaternionf1.mul(quaternionf4);
|
||||
matrix3f3.transpose().mul(matrix3f2);
|
||||
if (flag1) {
|
||||
givensparameters = qrGivensQuat(matrix3f3.m22, -matrix3f3.m21);
|
||||
} else {
|
||||
givensparameters = qrGivensQuat(matrix3f3.m11, matrix3f3.m12);
|
||||
}
|
||||
|
||||
Quaternionf quaternionf5 = givensparameters.aroundX(quaternionf2);
|
||||
Matrix3f matrix3f4 = givensparameters.aroundX(matrix3f2);
|
||||
quaternionf1.mul(quaternionf5);
|
||||
matrix3f4.transpose().mul(matrix3f3);
|
||||
Vector3f vector3f = new Vector3f(matrix3f4.m00, matrix3f4.m11, matrix3f4.m22);
|
||||
return Triple.of(quaternionf1, vector3f, quaternionf.conjugate());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.mojang.math;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.meta.TypeQualifierDefault;
|
||||
|
||||
@Nonnull
|
||||
@TypeQualifierDefault({ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface MethodsReturnNonnullByDefault {
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
package com.mojang.math;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import it.unimi.dsi.fastutil.booleans.BooleanArrayList;
|
||||
import it.unimi.dsi.fastutil.booleans.BooleanList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.FrontAndTop;
|
||||
import net.minecraft.util.StringRepresentable;
|
||||
import org.joml.Matrix3f;
|
||||
|
||||
public enum OctahedralGroup implements StringRepresentable {
|
||||
IDENTITY("identity", SymmetricGroup3.P123, false, false, false),
|
||||
ROT_180_FACE_XY("rot_180_face_xy", SymmetricGroup3.P123, true, true, false),
|
||||
ROT_180_FACE_XZ("rot_180_face_xz", SymmetricGroup3.P123, true, false, true),
|
||||
ROT_180_FACE_YZ("rot_180_face_yz", SymmetricGroup3.P123, false, true, true),
|
||||
ROT_120_NNN("rot_120_nnn", SymmetricGroup3.P231, false, false, false),
|
||||
ROT_120_NNP("rot_120_nnp", SymmetricGroup3.P312, true, false, true),
|
||||
ROT_120_NPN("rot_120_npn", SymmetricGroup3.P312, false, true, true),
|
||||
ROT_120_NPP("rot_120_npp", SymmetricGroup3.P231, true, false, true),
|
||||
ROT_120_PNN("rot_120_pnn", SymmetricGroup3.P312, true, true, false),
|
||||
ROT_120_PNP("rot_120_pnp", SymmetricGroup3.P231, true, true, false),
|
||||
ROT_120_PPN("rot_120_ppn", SymmetricGroup3.P231, false, true, true),
|
||||
ROT_120_PPP("rot_120_ppp", SymmetricGroup3.P312, false, false, false),
|
||||
ROT_180_EDGE_XY_NEG("rot_180_edge_xy_neg", SymmetricGroup3.P213, true, true, true),
|
||||
ROT_180_EDGE_XY_POS("rot_180_edge_xy_pos", SymmetricGroup3.P213, false, false, true),
|
||||
ROT_180_EDGE_XZ_NEG("rot_180_edge_xz_neg", SymmetricGroup3.P321, true, true, true),
|
||||
ROT_180_EDGE_XZ_POS("rot_180_edge_xz_pos", SymmetricGroup3.P321, false, true, false),
|
||||
ROT_180_EDGE_YZ_NEG("rot_180_edge_yz_neg", SymmetricGroup3.P132, true, true, true),
|
||||
ROT_180_EDGE_YZ_POS("rot_180_edge_yz_pos", SymmetricGroup3.P132, true, false, false),
|
||||
ROT_90_X_NEG("rot_90_x_neg", SymmetricGroup3.P132, false, false, true),
|
||||
ROT_90_X_POS("rot_90_x_pos", SymmetricGroup3.P132, false, true, false),
|
||||
ROT_90_Y_NEG("rot_90_y_neg", SymmetricGroup3.P321, true, false, false),
|
||||
ROT_90_Y_POS("rot_90_y_pos", SymmetricGroup3.P321, false, false, true),
|
||||
ROT_90_Z_NEG("rot_90_z_neg", SymmetricGroup3.P213, false, true, false),
|
||||
ROT_90_Z_POS("rot_90_z_pos", SymmetricGroup3.P213, true, false, false),
|
||||
INVERSION("inversion", SymmetricGroup3.P123, true, true, true),
|
||||
INVERT_X("invert_x", SymmetricGroup3.P123, true, false, false),
|
||||
INVERT_Y("invert_y", SymmetricGroup3.P123, false, true, false),
|
||||
INVERT_Z("invert_z", SymmetricGroup3.P123, false, false, true),
|
||||
ROT_60_REF_NNN("rot_60_ref_nnn", SymmetricGroup3.P312, true, true, true),
|
||||
ROT_60_REF_NNP("rot_60_ref_nnp", SymmetricGroup3.P231, true, false, false),
|
||||
ROT_60_REF_NPN("rot_60_ref_npn", SymmetricGroup3.P231, false, false, true),
|
||||
ROT_60_REF_NPP("rot_60_ref_npp", SymmetricGroup3.P312, false, false, true),
|
||||
ROT_60_REF_PNN("rot_60_ref_pnn", SymmetricGroup3.P231, false, true, false),
|
||||
ROT_60_REF_PNP("rot_60_ref_pnp", SymmetricGroup3.P312, true, false, false),
|
||||
ROT_60_REF_PPN("rot_60_ref_ppn", SymmetricGroup3.P312, false, true, false),
|
||||
ROT_60_REF_PPP("rot_60_ref_ppp", SymmetricGroup3.P231, true, true, true),
|
||||
SWAP_XY("swap_xy", SymmetricGroup3.P213, false, false, false),
|
||||
SWAP_YZ("swap_yz", SymmetricGroup3.P132, false, false, false),
|
||||
SWAP_XZ("swap_xz", SymmetricGroup3.P321, false, false, false),
|
||||
SWAP_NEG_XY("swap_neg_xy", SymmetricGroup3.P213, true, true, false),
|
||||
SWAP_NEG_YZ("swap_neg_yz", SymmetricGroup3.P132, false, true, true),
|
||||
SWAP_NEG_XZ("swap_neg_xz", SymmetricGroup3.P321, true, false, true),
|
||||
ROT_90_REF_X_NEG("rot_90_ref_x_neg", SymmetricGroup3.P132, true, false, true),
|
||||
ROT_90_REF_X_POS("rot_90_ref_x_pos", SymmetricGroup3.P132, true, true, false),
|
||||
ROT_90_REF_Y_NEG("rot_90_ref_y_neg", SymmetricGroup3.P321, true, true, false),
|
||||
ROT_90_REF_Y_POS("rot_90_ref_y_pos", SymmetricGroup3.P321, false, true, true),
|
||||
ROT_90_REF_Z_NEG("rot_90_ref_z_neg", SymmetricGroup3.P213, false, true, true),
|
||||
ROT_90_REF_Z_POS("rot_90_ref_z_pos", SymmetricGroup3.P213, true, false, true);
|
||||
|
||||
private final Matrix3f transformation;
|
||||
private final String name;
|
||||
@Nullable
|
||||
private Map<Direction, Direction> rotatedDirections;
|
||||
private final boolean invertX;
|
||||
private final boolean invertY;
|
||||
private final boolean invertZ;
|
||||
private final SymmetricGroup3 permutation;
|
||||
private static final OctahedralGroup[][] cayleyTable = Util.make(new OctahedralGroup[values().length][values().length], (p_56533_) -> {
|
||||
Map<Pair<SymmetricGroup3, BooleanList>, OctahedralGroup> map = Arrays.stream(values()).collect(Collectors.toMap((p_174952_) -> {
|
||||
return Pair.of(p_174952_.permutation, p_174952_.packInversions());
|
||||
}, (p_174950_) -> {
|
||||
return p_174950_;
|
||||
}));
|
||||
|
||||
for(OctahedralGroup octahedralgroup : values()) {
|
||||
for(OctahedralGroup octahedralgroup1 : values()) {
|
||||
BooleanList booleanlist = octahedralgroup.packInversions();
|
||||
BooleanList booleanlist1 = octahedralgroup1.packInversions();
|
||||
SymmetricGroup3 symmetricgroup3 = octahedralgroup1.permutation.compose(octahedralgroup.permutation);
|
||||
BooleanArrayList booleanarraylist = new BooleanArrayList(3);
|
||||
|
||||
for(int i = 0; i < 3; ++i) {
|
||||
booleanarraylist.add(booleanlist.getBoolean(i) ^ booleanlist1.getBoolean(octahedralgroup.permutation.permutation(i)));
|
||||
}
|
||||
|
||||
p_56533_[octahedralgroup.ordinal()][octahedralgroup1.ordinal()] = map.get(Pair.of(symmetricgroup3, booleanarraylist));
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
private static final OctahedralGroup[] inverseTable = Arrays.stream(values()).map((p_56536_) -> {
|
||||
return Arrays.stream(values()).filter((p_174947_) -> {
|
||||
return p_56536_.compose(p_174947_) == IDENTITY;
|
||||
}).findAny().get();
|
||||
}).toArray((p_56520_) -> {
|
||||
return new OctahedralGroup[p_56520_];
|
||||
});
|
||||
|
||||
private OctahedralGroup(String p_56513_, SymmetricGroup3 p_56514_, boolean p_56515_, boolean p_56516_, boolean p_56517_) {
|
||||
this.name = p_56513_;
|
||||
this.invertX = p_56515_;
|
||||
this.invertY = p_56516_;
|
||||
this.invertZ = p_56517_;
|
||||
this.permutation = p_56514_;
|
||||
this.transformation = (new Matrix3f()).scaling(p_56515_ ? -1.0F : 1.0F, p_56516_ ? -1.0F : 1.0F, p_56517_ ? -1.0F : 1.0F);
|
||||
this.transformation.mul(p_56514_.transformation());
|
||||
}
|
||||
|
||||
private BooleanList packInversions() {
|
||||
return new BooleanArrayList(new boolean[]{this.invertX, this.invertY, this.invertZ});
|
||||
}
|
||||
|
||||
public OctahedralGroup compose(OctahedralGroup p_56522_) {
|
||||
return cayleyTable[this.ordinal()][p_56522_.ordinal()];
|
||||
}
|
||||
|
||||
public OctahedralGroup inverse() {
|
||||
return inverseTable[this.ordinal()];
|
||||
}
|
||||
|
||||
public Matrix3f transformation() {
|
||||
return new Matrix3f(this.transformation);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getSerializedName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public Direction rotate(Direction p_56529_) {
|
||||
if (this.rotatedDirections == null) {
|
||||
this.rotatedDirections = Maps.newEnumMap(Direction.class);
|
||||
Direction.Axis[] adirection$axis = Direction.Axis.values();
|
||||
|
||||
for(Direction direction : Direction.values()) {
|
||||
Direction.Axis direction$axis = direction.getAxis();
|
||||
Direction.AxisDirection direction$axisdirection = direction.getAxisDirection();
|
||||
Direction.Axis direction$axis1 = adirection$axis[this.permutation.permutation(direction$axis.ordinal())];
|
||||
Direction.AxisDirection direction$axisdirection1 = this.inverts(direction$axis1) ? direction$axisdirection.opposite() : direction$axisdirection;
|
||||
Direction direction1 = Direction.fromAxisAndDirection(direction$axis1, direction$axisdirection1);
|
||||
this.rotatedDirections.put(direction, direction1);
|
||||
}
|
||||
}
|
||||
|
||||
return this.rotatedDirections.get(p_56529_);
|
||||
}
|
||||
|
||||
public boolean inverts(Direction.Axis p_56527_) {
|
||||
switch (p_56527_) {
|
||||
case X:
|
||||
return this.invertX;
|
||||
case Y:
|
||||
return this.invertY;
|
||||
case Z:
|
||||
default:
|
||||
return this.invertZ;
|
||||
}
|
||||
}
|
||||
|
||||
public FrontAndTop rotate(FrontAndTop p_56531_) {
|
||||
return FrontAndTop.fromFrontAndTop(this.rotate(p_56531_.front()), this.rotate(p_56531_.top()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.mojang.math;
|
||||
|
||||
import java.util.Arrays;
|
||||
import net.minecraft.Util;
|
||||
import org.joml.Matrix3f;
|
||||
|
||||
public enum SymmetricGroup3 {
|
||||
P123(0, 1, 2),
|
||||
P213(1, 0, 2),
|
||||
P132(0, 2, 1),
|
||||
P231(1, 2, 0),
|
||||
P312(2, 0, 1),
|
||||
P321(2, 1, 0);
|
||||
|
||||
private final int[] permutation;
|
||||
private final Matrix3f transformation;
|
||||
private static final int ORDER = 3;
|
||||
private static final SymmetricGroup3[][] cayleyTable = Util.make(new SymmetricGroup3[values().length][values().length], (p_109188_) -> {
|
||||
for(SymmetricGroup3 symmetricgroup3 : values()) {
|
||||
for(SymmetricGroup3 symmetricgroup31 : values()) {
|
||||
int[] aint = new int[3];
|
||||
|
||||
for(int i = 0; i < 3; ++i) {
|
||||
aint[i] = symmetricgroup3.permutation[symmetricgroup31.permutation[i]];
|
||||
}
|
||||
|
||||
SymmetricGroup3 symmetricgroup32 = Arrays.stream(values()).filter((p_175577_) -> {
|
||||
return Arrays.equals(p_175577_.permutation, aint);
|
||||
}).findFirst().get();
|
||||
p_109188_[symmetricgroup3.ordinal()][symmetricgroup31.ordinal()] = symmetricgroup32;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
private SymmetricGroup3(int p_109176_, int p_109177_, int p_109178_) {
|
||||
this.permutation = new int[]{p_109176_, p_109177_, p_109178_};
|
||||
this.transformation = new Matrix3f();
|
||||
this.transformation.set(this.permutation(0), 0, 1.0F);
|
||||
this.transformation.set(this.permutation(1), 1, 1.0F);
|
||||
this.transformation.set(this.permutation(2), 2, 1.0F);
|
||||
}
|
||||
|
||||
public SymmetricGroup3 compose(SymmetricGroup3 p_109183_) {
|
||||
return cayleyTable[this.ordinal()][p_109183_.ordinal()];
|
||||
}
|
||||
|
||||
public int permutation(int p_109181_) {
|
||||
return this.permutation[p_109181_];
|
||||
}
|
||||
|
||||
public Matrix3f transformation() {
|
||||
return this.transformation;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
package com.mojang.math;
|
||||
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import java.util.Objects;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.util.ExtraCodecs;
|
||||
import org.apache.commons.lang3.tuple.Triple;
|
||||
import org.joml.Matrix3f;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector3fc;
|
||||
|
||||
public final class Transformation implements net.minecraftforge.common.extensions.IForgeTransformation {
|
||||
private final Matrix4f matrix;
|
||||
public static final Codec<Transformation> CODEC = RecordCodecBuilder.create((p_269604_) -> {
|
||||
return p_269604_.group(ExtraCodecs.VECTOR3F.fieldOf("translation").forGetter((p_269599_) -> {
|
||||
return p_269599_.translation;
|
||||
}), ExtraCodecs.QUATERNIONF.fieldOf("left_rotation").forGetter((p_269600_) -> {
|
||||
return p_269600_.leftRotation;
|
||||
}), ExtraCodecs.VECTOR3F.fieldOf("scale").forGetter((p_269603_) -> {
|
||||
return p_269603_.scale;
|
||||
}), ExtraCodecs.QUATERNIONF.fieldOf("right_rotation").forGetter((p_269598_) -> {
|
||||
return p_269598_.rightRotation;
|
||||
})).apply(p_269604_, Transformation::new);
|
||||
});
|
||||
public static final Codec<Transformation> EXTENDED_CODEC = Codec.either(CODEC, ExtraCodecs.MATRIX4F.xmap(Transformation::new, Transformation::getMatrix)).xmap((p_269605_) -> {
|
||||
return p_269605_.map((p_269601_) -> {
|
||||
return p_269601_;
|
||||
}, (p_269602_) -> {
|
||||
return p_269602_;
|
||||
});
|
||||
}, Either::left);
|
||||
private boolean decomposed;
|
||||
@Nullable
|
||||
private Vector3f translation;
|
||||
@Nullable
|
||||
private Quaternionf leftRotation;
|
||||
@Nullable
|
||||
private Vector3f scale;
|
||||
@Nullable
|
||||
private Quaternionf rightRotation;
|
||||
private static final Transformation IDENTITY = Util.make(() -> {
|
||||
Transformation transformation = new Transformation(new Matrix4f());
|
||||
transformation.translation = new Vector3f();
|
||||
transformation.leftRotation = new Quaternionf();
|
||||
transformation.scale = new Vector3f(1.0F, 1.0F, 1.0F);
|
||||
transformation.rightRotation = new Quaternionf();
|
||||
transformation.decomposed = true;
|
||||
return transformation;
|
||||
});
|
||||
|
||||
public Transformation(@Nullable Matrix4f p_253689_) {
|
||||
if (p_253689_ == null) {
|
||||
this.matrix = new Matrix4f();
|
||||
} else {
|
||||
this.matrix = p_253689_;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Transformation(@Nullable Vector3f p_253831_, @Nullable Quaternionf p_253846_, @Nullable Vector3f p_254502_, @Nullable Quaternionf p_253912_) {
|
||||
this.matrix = compose(p_253831_, p_253846_, p_254502_, p_253912_);
|
||||
this.translation = p_253831_ != null ? p_253831_ : new Vector3f();
|
||||
this.leftRotation = p_253846_ != null ? p_253846_ : new Quaternionf();
|
||||
this.scale = p_254502_ != null ? p_254502_ : new Vector3f(1.0F, 1.0F, 1.0F);
|
||||
this.rightRotation = p_253912_ != null ? p_253912_ : new Quaternionf();
|
||||
this.decomposed = true;
|
||||
}
|
||||
|
||||
public static Transformation identity() {
|
||||
return IDENTITY;
|
||||
}
|
||||
|
||||
public Transformation compose(Transformation p_121097_) {
|
||||
Matrix4f matrix4f = this.getMatrix();
|
||||
matrix4f.mul(p_121097_.getMatrix());
|
||||
return new Transformation(matrix4f);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Transformation inverse() {
|
||||
if (this == IDENTITY) {
|
||||
return this;
|
||||
} else {
|
||||
Matrix4f matrix4f = this.getMatrix().invert();
|
||||
return matrix4f.isFinite() ? new Transformation(matrix4f) : null;
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureDecomposed() {
|
||||
if (!this.decomposed) {
|
||||
float f = 1.0F / this.matrix.m33();
|
||||
Triple<Quaternionf, Vector3f, Quaternionf> triple = MatrixUtil.svdDecompose((new Matrix3f(this.matrix)).scale(f));
|
||||
this.translation = this.matrix.getTranslation(new Vector3f()).mul(f);
|
||||
this.leftRotation = new Quaternionf(triple.getLeft());
|
||||
this.scale = new Vector3f(triple.getMiddle());
|
||||
this.rightRotation = new Quaternionf(triple.getRight());
|
||||
this.decomposed = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static Matrix4f compose(@Nullable Vector3f p_254465_, @Nullable Quaternionf p_254416_, @Nullable Vector3f p_254499_, @Nullable Quaternionf p_254334_) {
|
||||
Matrix4f matrix4f = new Matrix4f();
|
||||
if (p_254465_ != null) {
|
||||
matrix4f.translation(p_254465_);
|
||||
}
|
||||
|
||||
if (p_254416_ != null) {
|
||||
matrix4f.rotate(p_254416_);
|
||||
}
|
||||
|
||||
if (p_254499_ != null) {
|
||||
matrix4f.scale(p_254499_);
|
||||
}
|
||||
|
||||
if (p_254334_ != null) {
|
||||
matrix4f.rotate(p_254334_);
|
||||
}
|
||||
|
||||
return matrix4f;
|
||||
}
|
||||
|
||||
public Matrix4f getMatrix() {
|
||||
return new Matrix4f(this.matrix);
|
||||
}
|
||||
|
||||
public Vector3f getTranslation() {
|
||||
this.ensureDecomposed();
|
||||
return new Vector3f((Vector3fc)this.translation);
|
||||
}
|
||||
|
||||
public Quaternionf getLeftRotation() {
|
||||
this.ensureDecomposed();
|
||||
return new Quaternionf(this.leftRotation);
|
||||
}
|
||||
|
||||
public Vector3f getScale() {
|
||||
this.ensureDecomposed();
|
||||
return new Vector3f((Vector3fc)this.scale);
|
||||
}
|
||||
|
||||
public Quaternionf getRightRotation() {
|
||||
this.ensureDecomposed();
|
||||
return new Quaternionf(this.rightRotation);
|
||||
}
|
||||
|
||||
public boolean equals(Object p_121108_) {
|
||||
if (this == p_121108_) {
|
||||
return true;
|
||||
} else if (p_121108_ != null && this.getClass() == p_121108_.getClass()) {
|
||||
Transformation transformation = (Transformation)p_121108_;
|
||||
return Objects.equals(this.matrix, transformation.matrix);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.matrix);
|
||||
}
|
||||
|
||||
private Matrix3f normalTransform = null;
|
||||
public Matrix3f getNormalMatrix() {
|
||||
checkNormalTransform();
|
||||
return normalTransform;
|
||||
}
|
||||
private void checkNormalTransform() {
|
||||
if (normalTransform == null) {
|
||||
normalTransform = new Matrix3f(matrix);
|
||||
normalTransform.invert();
|
||||
normalTransform.transpose();
|
||||
}
|
||||
}
|
||||
|
||||
public Transformation slerp(Transformation p_175938_, float p_175939_) {
|
||||
Vector3f vector3f = this.getTranslation();
|
||||
Quaternionf quaternionf = this.getLeftRotation();
|
||||
Vector3f vector3f1 = this.getScale();
|
||||
Quaternionf quaternionf1 = this.getRightRotation();
|
||||
vector3f.lerp(p_175938_.getTranslation(), p_175939_);
|
||||
quaternionf.slerp(p_175938_.getLeftRotation(), p_175939_);
|
||||
vector3f1.lerp(p_175938_.getScale(), p_175939_);
|
||||
quaternionf1.slerp(p_175938_.getRightRotation(), p_175939_);
|
||||
return new Transformation(vector3f, quaternionf, vector3f1, quaternionf1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
package com.mojang.math;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.mojang.realmsclient;
|
||||
|
||||
import java.util.Arrays;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class KeyCombo {
|
||||
private final char[] chars;
|
||||
private int matchIndex;
|
||||
private final Runnable onCompletion;
|
||||
|
||||
public KeyCombo(char[] p_86225_, Runnable p_86226_) {
|
||||
this.onCompletion = p_86226_;
|
||||
if (p_86225_.length < 1) {
|
||||
throw new IllegalArgumentException("Must have at least one char");
|
||||
} else {
|
||||
this.chars = p_86225_;
|
||||
}
|
||||
}
|
||||
|
||||
public KeyCombo(char[] p_167171_) {
|
||||
this(p_167171_, () -> {
|
||||
});
|
||||
}
|
||||
|
||||
public boolean keyPressed(char p_86229_) {
|
||||
if (p_86229_ == this.chars[this.matchIndex++]) {
|
||||
if (this.matchIndex == this.chars.length) {
|
||||
this.reset();
|
||||
this.onCompletion.run();
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
this.matchIndex = 0;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "KeyCombo{chars=" + Arrays.toString(this.chars) + ", matchIndex=" + this.matchIndex + "}";
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,48 @@
|
||||
package com.mojang.realmsclient;
|
||||
|
||||
import java.util.Locale;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public enum Unit {
|
||||
B,
|
||||
KB,
|
||||
MB,
|
||||
GB;
|
||||
|
||||
private static final int BASE_UNIT = 1024;
|
||||
|
||||
public static Unit getLargest(long p_86941_) {
|
||||
if (p_86941_ < 1024L) {
|
||||
return B;
|
||||
} else {
|
||||
try {
|
||||
int i = (int)(Math.log((double)p_86941_) / Math.log(1024.0D));
|
||||
String s = String.valueOf("KMGTPE".charAt(i - 1));
|
||||
return valueOf(s + "B");
|
||||
} catch (Exception exception) {
|
||||
return GB;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static double convertTo(long p_86943_, Unit p_86944_) {
|
||||
return p_86944_ == B ? (double)p_86943_ : (double)p_86943_ / Math.pow(1024.0D, (double)p_86944_.ordinal());
|
||||
}
|
||||
|
||||
public static String humanReadable(long p_86946_) {
|
||||
int i = 1024;
|
||||
if (p_86946_ < 1024L) {
|
||||
return p_86946_ + " B";
|
||||
} else {
|
||||
int j = (int)(Math.log((double)p_86946_) / Math.log(1024.0D));
|
||||
String s = "" + "KMGTPE".charAt(j - 1);
|
||||
return String.format(Locale.ROOT, "%.1f %sB", (double)p_86946_ / Math.pow(1024.0D, (double)j), s);
|
||||
}
|
||||
}
|
||||
|
||||
public static String humanReadable(long p_86948_, Unit p_86949_) {
|
||||
return String.format(Locale.ROOT, "%." + (p_86949_ == GB ? "1" : "0") + "f %s", convertTo(p_86948_, p_86949_), p_86949_.name());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,408 @@
|
||||
package com.mojang.realmsclient.client;
|
||||
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.google.common.io.Files;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.dto.WorldDownload;
|
||||
import com.mojang.realmsclient.exception.RealmsDefaultUncaughtExceptionHandler;
|
||||
import com.mojang.realmsclient.gui.screens.RealmsDownloadLatestWorldScreen;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtIo;
|
||||
import net.minecraft.world.level.storage.LevelResource;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||
import net.minecraft.world.level.validation.ContentValidationException;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.io.output.CountingOutputStream;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class FileDownload {
|
||||
static final Logger LOGGER = LogUtils.getLogger();
|
||||
volatile boolean cancelled;
|
||||
volatile boolean finished;
|
||||
volatile boolean error;
|
||||
volatile boolean extracting;
|
||||
@Nullable
|
||||
private volatile File tempFile;
|
||||
volatile File resourcePackPath;
|
||||
@Nullable
|
||||
private volatile HttpGet request;
|
||||
@Nullable
|
||||
private Thread currentThread;
|
||||
private final RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(120000).setConnectTimeout(120000).build();
|
||||
private static final String[] INVALID_FILE_NAMES = new String[]{"CON", "COM", "PRN", "AUX", "CLOCK$", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"};
|
||||
|
||||
public long contentLength(String p_86990_) {
|
||||
CloseableHttpClient closeablehttpclient = null;
|
||||
HttpGet httpget = null;
|
||||
|
||||
long i;
|
||||
try {
|
||||
httpget = new HttpGet(p_86990_);
|
||||
closeablehttpclient = HttpClientBuilder.create().setDefaultRequestConfig(this.requestConfig).build();
|
||||
CloseableHttpResponse closeablehttpresponse = closeablehttpclient.execute(httpget);
|
||||
return Long.parseLong(closeablehttpresponse.getFirstHeader("Content-Length").getValue());
|
||||
} catch (Throwable throwable) {
|
||||
LOGGER.error("Unable to get content length for download");
|
||||
i = 0L;
|
||||
} finally {
|
||||
if (httpget != null) {
|
||||
httpget.releaseConnection();
|
||||
}
|
||||
|
||||
if (closeablehttpclient != null) {
|
||||
try {
|
||||
closeablehttpclient.close();
|
||||
} catch (IOException ioexception) {
|
||||
LOGGER.error("Could not close http client", (Throwable)ioexception);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public void download(WorldDownload p_86983_, String p_86984_, RealmsDownloadLatestWorldScreen.DownloadStatus p_86985_, LevelStorageSource p_86986_) {
|
||||
if (this.currentThread == null) {
|
||||
this.currentThread = new Thread(() -> {
|
||||
CloseableHttpClient closeablehttpclient = null;
|
||||
|
||||
try {
|
||||
this.tempFile = File.createTempFile("backup", ".tar.gz");
|
||||
this.request = new HttpGet(p_86983_.downloadLink);
|
||||
closeablehttpclient = HttpClientBuilder.create().setDefaultRequestConfig(this.requestConfig).build();
|
||||
HttpResponse httpresponse = closeablehttpclient.execute(this.request);
|
||||
p_86985_.totalBytes = Long.parseLong(httpresponse.getFirstHeader("Content-Length").getValue());
|
||||
if (httpresponse.getStatusLine().getStatusCode() == 200) {
|
||||
OutputStream outputstream = new FileOutputStream(this.tempFile);
|
||||
FileDownload.ProgressListener filedownload$progresslistener = new FileDownload.ProgressListener(p_86984_.trim(), this.tempFile, p_86986_, p_86985_);
|
||||
FileDownload.DownloadCountingOutputStream filedownload$downloadcountingoutputstream = new FileDownload.DownloadCountingOutputStream(outputstream);
|
||||
filedownload$downloadcountingoutputstream.setListener(filedownload$progresslistener);
|
||||
IOUtils.copy(httpresponse.getEntity().getContent(), filedownload$downloadcountingoutputstream);
|
||||
return;
|
||||
}
|
||||
|
||||
this.error = true;
|
||||
this.request.abort();
|
||||
} catch (Exception exception1) {
|
||||
LOGGER.error("Caught exception while downloading: {}", (Object)exception1.getMessage());
|
||||
this.error = true;
|
||||
return;
|
||||
} finally {
|
||||
this.request.releaseConnection();
|
||||
if (this.tempFile != null) {
|
||||
this.tempFile.delete();
|
||||
}
|
||||
|
||||
if (!this.error) {
|
||||
if (!p_86983_.resourcePackUrl.isEmpty() && !p_86983_.resourcePackHash.isEmpty()) {
|
||||
try {
|
||||
this.tempFile = File.createTempFile("resources", ".tar.gz");
|
||||
this.request = new HttpGet(p_86983_.resourcePackUrl);
|
||||
HttpResponse httpresponse1 = closeablehttpclient.execute(this.request);
|
||||
p_86985_.totalBytes = Long.parseLong(httpresponse1.getFirstHeader("Content-Length").getValue());
|
||||
if (httpresponse1.getStatusLine().getStatusCode() != 200) {
|
||||
this.error = true;
|
||||
this.request.abort();
|
||||
return;
|
||||
}
|
||||
|
||||
OutputStream outputstream1 = new FileOutputStream(this.tempFile);
|
||||
FileDownload.ResourcePackProgressListener filedownload$resourcepackprogresslistener = new FileDownload.ResourcePackProgressListener(this.tempFile, p_86985_, p_86983_);
|
||||
FileDownload.DownloadCountingOutputStream filedownload$downloadcountingoutputstream1 = new FileDownload.DownloadCountingOutputStream(outputstream1);
|
||||
filedownload$downloadcountingoutputstream1.setListener(filedownload$resourcepackprogresslistener);
|
||||
IOUtils.copy(httpresponse1.getEntity().getContent(), filedownload$downloadcountingoutputstream1);
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Caught exception while downloading: {}", (Object)exception.getMessage());
|
||||
this.error = true;
|
||||
} finally {
|
||||
this.request.releaseConnection();
|
||||
if (this.tempFile != null) {
|
||||
this.tempFile.delete();
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
this.finished = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (closeablehttpclient != null) {
|
||||
try {
|
||||
closeablehttpclient.close();
|
||||
} catch (IOException ioexception) {
|
||||
LOGGER.error("Failed to close Realms download client");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
this.currentThread.setUncaughtExceptionHandler(new RealmsDefaultUncaughtExceptionHandler(LOGGER));
|
||||
this.currentThread.start();
|
||||
}
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
if (this.request != null) {
|
||||
this.request.abort();
|
||||
}
|
||||
|
||||
if (this.tempFile != null) {
|
||||
this.tempFile.delete();
|
||||
}
|
||||
|
||||
this.cancelled = true;
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return this.finished;
|
||||
}
|
||||
|
||||
public boolean isError() {
|
||||
return this.error;
|
||||
}
|
||||
|
||||
public boolean isExtracting() {
|
||||
return this.extracting;
|
||||
}
|
||||
|
||||
public static String findAvailableFolderName(String p_87002_) {
|
||||
p_87002_ = p_87002_.replaceAll("[\\./\"]", "_");
|
||||
|
||||
for(String s : INVALID_FILE_NAMES) {
|
||||
if (p_87002_.equalsIgnoreCase(s)) {
|
||||
p_87002_ = "_" + p_87002_ + "_";
|
||||
}
|
||||
}
|
||||
|
||||
return p_87002_;
|
||||
}
|
||||
|
||||
void untarGzipArchive(String p_86992_, @Nullable File p_86993_, LevelStorageSource p_86994_) throws IOException {
|
||||
Pattern pattern = Pattern.compile(".*-([0-9]+)$");
|
||||
int i = 1;
|
||||
|
||||
for(char c0 : SharedConstants.ILLEGAL_FILE_CHARACTERS) {
|
||||
p_86992_ = p_86992_.replace(c0, '_');
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty(p_86992_)) {
|
||||
p_86992_ = "Realm";
|
||||
}
|
||||
|
||||
p_86992_ = findAvailableFolderName(p_86992_);
|
||||
|
||||
try {
|
||||
for(LevelStorageSource.LevelDirectory levelstoragesource$leveldirectory : p_86994_.findLevelCandidates()) {
|
||||
String s1 = levelstoragesource$leveldirectory.directoryName();
|
||||
if (s1.toLowerCase(Locale.ROOT).startsWith(p_86992_.toLowerCase(Locale.ROOT))) {
|
||||
Matcher matcher = pattern.matcher(s1);
|
||||
if (matcher.matches()) {
|
||||
int j = Integer.parseInt(matcher.group(1));
|
||||
if (j > i) {
|
||||
i = j;
|
||||
}
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception exception1) {
|
||||
LOGGER.error("Error getting level list", (Throwable)exception1);
|
||||
this.error = true;
|
||||
return;
|
||||
}
|
||||
|
||||
String s;
|
||||
if (p_86994_.isNewLevelIdAcceptable(p_86992_) && i <= 1) {
|
||||
s = p_86992_;
|
||||
} else {
|
||||
s = p_86992_ + (i == 1 ? "" : "-" + i);
|
||||
if (!p_86994_.isNewLevelIdAcceptable(s)) {
|
||||
boolean flag = false;
|
||||
|
||||
while(!flag) {
|
||||
++i;
|
||||
s = p_86992_ + (i == 1 ? "" : "-" + i);
|
||||
if (p_86994_.isNewLevelIdAcceptable(s)) {
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TarArchiveInputStream tararchiveinputstream = null;
|
||||
File file1 = new File(Minecraft.getInstance().gameDirectory.getAbsolutePath(), "saves");
|
||||
|
||||
try {
|
||||
file1.mkdir();
|
||||
tararchiveinputstream = new TarArchiveInputStream(new GzipCompressorInputStream(new BufferedInputStream(new FileInputStream(p_86993_))));
|
||||
|
||||
for(TarArchiveEntry tararchiveentry = tararchiveinputstream.getNextTarEntry(); tararchiveentry != null; tararchiveentry = tararchiveinputstream.getNextTarEntry()) {
|
||||
File file2 = new File(file1, tararchiveentry.getName().replace("world", s));
|
||||
if (tararchiveentry.isDirectory()) {
|
||||
file2.mkdirs();
|
||||
} else {
|
||||
file2.createNewFile();
|
||||
|
||||
try (FileOutputStream fileoutputstream = new FileOutputStream(file2)) {
|
||||
IOUtils.copy(tararchiveinputstream, fileoutputstream);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Error extracting world", (Throwable)exception);
|
||||
this.error = true;
|
||||
} finally {
|
||||
if (tararchiveinputstream != null) {
|
||||
tararchiveinputstream.close();
|
||||
}
|
||||
|
||||
if (p_86993_ != null) {
|
||||
p_86993_.delete();
|
||||
}
|
||||
|
||||
try (LevelStorageSource.LevelStorageAccess levelstoragesource$levelstorageaccess = p_86994_.validateAndCreateAccess(s)) {
|
||||
levelstoragesource$levelstorageaccess.renameLevel(s.trim());
|
||||
Path path = levelstoragesource$levelstorageaccess.getLevelPath(LevelResource.LEVEL_DATA_FILE);
|
||||
deletePlayerTag(path.toFile());
|
||||
} catch (IOException ioexception) {
|
||||
LOGGER.error("Failed to rename unpacked realms level {}", s, ioexception);
|
||||
} catch (ContentValidationException contentvalidationexception) {
|
||||
LOGGER.warn("{}", (Object)contentvalidationexception.getMessage());
|
||||
}
|
||||
|
||||
this.resourcePackPath = new File(file1, s + File.separator + "resources.zip");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void deletePlayerTag(File p_86988_) {
|
||||
if (p_86988_.exists()) {
|
||||
try {
|
||||
CompoundTag compoundtag = NbtIo.readCompressed(p_86988_);
|
||||
CompoundTag compoundtag1 = compoundtag.getCompound("Data");
|
||||
compoundtag1.remove("Player");
|
||||
NbtIo.writeCompressed(compoundtag, p_86988_);
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class DownloadCountingOutputStream extends CountingOutputStream {
|
||||
@Nullable
|
||||
private ActionListener listener;
|
||||
|
||||
public DownloadCountingOutputStream(OutputStream p_193509_) {
|
||||
super(p_193509_);
|
||||
}
|
||||
|
||||
public void setListener(ActionListener p_87017_) {
|
||||
this.listener = p_87017_;
|
||||
}
|
||||
|
||||
protected void afterWrite(int p_87019_) throws IOException {
|
||||
super.afterWrite(p_87019_);
|
||||
if (this.listener != null) {
|
||||
this.listener.actionPerformed(new ActionEvent(this, 0, (String)null));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class ProgressListener implements ActionListener {
|
||||
private final String worldName;
|
||||
private final File tempFile;
|
||||
private final LevelStorageSource levelStorageSource;
|
||||
private final RealmsDownloadLatestWorldScreen.DownloadStatus downloadStatus;
|
||||
|
||||
ProgressListener(String p_87027_, File p_87028_, LevelStorageSource p_87029_, RealmsDownloadLatestWorldScreen.DownloadStatus p_87030_) {
|
||||
this.worldName = p_87027_;
|
||||
this.tempFile = p_87028_;
|
||||
this.levelStorageSource = p_87029_;
|
||||
this.downloadStatus = p_87030_;
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent p_87039_) {
|
||||
this.downloadStatus.bytesWritten = ((FileDownload.DownloadCountingOutputStream)p_87039_.getSource()).getByteCount();
|
||||
if (this.downloadStatus.bytesWritten >= this.downloadStatus.totalBytes && !FileDownload.this.cancelled && !FileDownload.this.error) {
|
||||
try {
|
||||
FileDownload.this.extracting = true;
|
||||
FileDownload.this.untarGzipArchive(this.worldName, this.tempFile, this.levelStorageSource);
|
||||
} catch (IOException ioexception) {
|
||||
FileDownload.LOGGER.error("Error extracting archive", (Throwable)ioexception);
|
||||
FileDownload.this.error = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class ResourcePackProgressListener implements ActionListener {
|
||||
private final File tempFile;
|
||||
private final RealmsDownloadLatestWorldScreen.DownloadStatus downloadStatus;
|
||||
private final WorldDownload worldDownload;
|
||||
|
||||
ResourcePackProgressListener(File p_87046_, RealmsDownloadLatestWorldScreen.DownloadStatus p_87047_, WorldDownload p_87048_) {
|
||||
this.tempFile = p_87046_;
|
||||
this.downloadStatus = p_87047_;
|
||||
this.worldDownload = p_87048_;
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent p_87056_) {
|
||||
this.downloadStatus.bytesWritten = ((FileDownload.DownloadCountingOutputStream)p_87056_.getSource()).getByteCount();
|
||||
if (this.downloadStatus.bytesWritten >= this.downloadStatus.totalBytes && !FileDownload.this.cancelled) {
|
||||
try {
|
||||
String s = Hashing.sha1().hashBytes(Files.toByteArray(this.tempFile)).toString();
|
||||
if (s.equals(this.worldDownload.resourcePackHash)) {
|
||||
FileUtils.copyFile(this.tempFile, FileDownload.this.resourcePackPath);
|
||||
FileDownload.this.finished = true;
|
||||
} else {
|
||||
FileDownload.LOGGER.error("Resourcepack had wrong hash (expected {}, found {}). Deleting it.", this.worldDownload.resourcePackHash, s);
|
||||
FileUtils.deleteQuietly(this.tempFile);
|
||||
FileDownload.this.error = true;
|
||||
}
|
||||
} catch (IOException ioexception) {
|
||||
FileDownload.LOGGER.error("Error copying resourcepack file: {}", (Object)ioexception.getMessage());
|
||||
FileDownload.this.error = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
package com.mojang.realmsclient.client;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.dto.UploadInfo;
|
||||
import com.mojang.realmsclient.gui.screens.UploadResult;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.time.Duration;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Consumer;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.User;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.InputStreamEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.util.Args;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class FileUpload {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final int MAX_RETRIES = 5;
|
||||
private static final String UPLOAD_PATH = "/upload";
|
||||
private final File file;
|
||||
private final long worldId;
|
||||
private final int slotId;
|
||||
private final UploadInfo uploadInfo;
|
||||
private final String sessionId;
|
||||
private final String username;
|
||||
private final String clientVersion;
|
||||
private final UploadStatus uploadStatus;
|
||||
private final AtomicBoolean cancelled = new AtomicBoolean(false);
|
||||
@Nullable
|
||||
private CompletableFuture<UploadResult> uploadTask;
|
||||
private final RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout((int)TimeUnit.MINUTES.toMillis(10L)).setConnectTimeout((int)TimeUnit.SECONDS.toMillis(15L)).build();
|
||||
|
||||
public FileUpload(File p_87071_, long p_87072_, int p_87073_, UploadInfo p_87074_, User p_87075_, String p_87076_, UploadStatus p_87077_) {
|
||||
this.file = p_87071_;
|
||||
this.worldId = p_87072_;
|
||||
this.slotId = p_87073_;
|
||||
this.uploadInfo = p_87074_;
|
||||
this.sessionId = p_87075_.getSessionId();
|
||||
this.username = p_87075_.getName();
|
||||
this.clientVersion = p_87076_;
|
||||
this.uploadStatus = p_87077_;
|
||||
}
|
||||
|
||||
public void upload(Consumer<UploadResult> p_87085_) {
|
||||
if (this.uploadTask == null) {
|
||||
this.uploadTask = CompletableFuture.supplyAsync(() -> {
|
||||
return this.requestUpload(0);
|
||||
});
|
||||
this.uploadTask.thenAccept(p_87085_);
|
||||
}
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
this.cancelled.set(true);
|
||||
if (this.uploadTask != null) {
|
||||
this.uploadTask.cancel(false);
|
||||
this.uploadTask = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private UploadResult requestUpload(int p_87080_) {
|
||||
UploadResult.Builder uploadresult$builder = new UploadResult.Builder();
|
||||
if (this.cancelled.get()) {
|
||||
return uploadresult$builder.build();
|
||||
} else {
|
||||
this.uploadStatus.totalBytes = this.file.length();
|
||||
HttpPost httppost = new HttpPost(this.uploadInfo.getUploadEndpoint().resolve("/upload/" + this.worldId + "/" + this.slotId));
|
||||
CloseableHttpClient closeablehttpclient = HttpClientBuilder.create().setDefaultRequestConfig(this.requestConfig).build();
|
||||
|
||||
UploadResult uploadresult;
|
||||
try {
|
||||
this.setupRequest(httppost);
|
||||
HttpResponse httpresponse = closeablehttpclient.execute(httppost);
|
||||
long i = this.getRetryDelaySeconds(httpresponse);
|
||||
if (!this.shouldRetry(i, p_87080_)) {
|
||||
this.handleResponse(httpresponse, uploadresult$builder);
|
||||
return uploadresult$builder.build();
|
||||
}
|
||||
|
||||
uploadresult = this.retryUploadAfter(i, p_87080_);
|
||||
} catch (Exception exception) {
|
||||
if (!this.cancelled.get()) {
|
||||
LOGGER.error("Caught exception while uploading: ", (Throwable)exception);
|
||||
}
|
||||
|
||||
return uploadresult$builder.build();
|
||||
} finally {
|
||||
this.cleanup(httppost, closeablehttpclient);
|
||||
}
|
||||
|
||||
return uploadresult;
|
||||
}
|
||||
}
|
||||
|
||||
private void cleanup(HttpPost p_87094_, @Nullable CloseableHttpClient p_87095_) {
|
||||
p_87094_.releaseConnection();
|
||||
if (p_87095_ != null) {
|
||||
try {
|
||||
p_87095_.close();
|
||||
} catch (IOException ioexception) {
|
||||
LOGGER.error("Failed to close Realms upload client");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void setupRequest(HttpPost p_87092_) throws FileNotFoundException {
|
||||
p_87092_.setHeader("Cookie", "sid=" + this.sessionId + ";token=" + this.uploadInfo.getToken() + ";user=" + this.username + ";version=" + this.clientVersion);
|
||||
FileUpload.CustomInputStreamEntity fileupload$custominputstreamentity = new FileUpload.CustomInputStreamEntity(new FileInputStream(this.file), this.file.length(), this.uploadStatus);
|
||||
fileupload$custominputstreamentity.setContentType("application/octet-stream");
|
||||
p_87092_.setEntity(fileupload$custominputstreamentity);
|
||||
}
|
||||
|
||||
private void handleResponse(HttpResponse p_87089_, UploadResult.Builder p_87090_) throws IOException {
|
||||
int i = p_87089_.getStatusLine().getStatusCode();
|
||||
if (i == 401) {
|
||||
LOGGER.debug("Realms server returned 401: {}", (Object)p_87089_.getFirstHeader("WWW-Authenticate"));
|
||||
}
|
||||
|
||||
p_87090_.withStatusCode(i);
|
||||
if (p_87089_.getEntity() != null) {
|
||||
String s = EntityUtils.toString(p_87089_.getEntity(), "UTF-8");
|
||||
if (s != null) {
|
||||
try {
|
||||
JsonParser jsonparser = new JsonParser();
|
||||
JsonElement jsonelement = jsonparser.parse(s).getAsJsonObject().get("errorMsg");
|
||||
Optional<String> optional = Optional.ofNullable(jsonelement).map(JsonElement::getAsString);
|
||||
p_87090_.withErrorMessage(optional.orElse((String)null));
|
||||
} catch (Exception exception) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean shouldRetry(long p_87082_, int p_87083_) {
|
||||
return p_87082_ > 0L && p_87083_ + 1 < 5;
|
||||
}
|
||||
|
||||
private UploadResult retryUploadAfter(long p_87098_, int p_87099_) throws InterruptedException {
|
||||
Thread.sleep(Duration.ofSeconds(p_87098_).toMillis());
|
||||
return this.requestUpload(p_87099_ + 1);
|
||||
}
|
||||
|
||||
private long getRetryDelaySeconds(HttpResponse p_87087_) {
|
||||
return Optional.ofNullable(p_87087_.getFirstHeader("Retry-After")).map(NameValuePair::getValue).map(Long::valueOf).orElse(0L);
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return this.uploadTask.isDone() || this.uploadTask.isCancelled();
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class CustomInputStreamEntity extends InputStreamEntity {
|
||||
private final long length;
|
||||
private final InputStream content;
|
||||
private final UploadStatus uploadStatus;
|
||||
|
||||
public CustomInputStreamEntity(InputStream p_87105_, long p_87106_, UploadStatus p_87107_) {
|
||||
super(p_87105_);
|
||||
this.content = p_87105_;
|
||||
this.length = p_87106_;
|
||||
this.uploadStatus = p_87107_;
|
||||
}
|
||||
|
||||
public void writeTo(OutputStream p_87109_) throws IOException {
|
||||
Args.notNull(p_87109_, "Output stream");
|
||||
InputStream inputstream = this.content;
|
||||
|
||||
try {
|
||||
byte[] abyte = new byte[4096];
|
||||
int j;
|
||||
if (this.length < 0L) {
|
||||
while((j = inputstream.read(abyte)) != -1) {
|
||||
p_87109_.write(abyte, 0, j);
|
||||
this.uploadStatus.bytesWritten += (long)j;
|
||||
}
|
||||
} else {
|
||||
long i = this.length;
|
||||
|
||||
while(i > 0L) {
|
||||
j = inputstream.read(abyte, 0, (int)Math.min(4096L, i));
|
||||
if (j == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
p_87109_.write(abyte, 0, j);
|
||||
this.uploadStatus.bytesWritten += (long)j;
|
||||
i -= (long)j;
|
||||
p_87109_.flush();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
inputstream.close();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.mojang.realmsclient.client;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.realmsclient.dto.RegionPingResult;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class Ping {
|
||||
public static List<RegionPingResult> ping(Ping.Region... p_87131_) {
|
||||
for(Ping.Region ping$region : p_87131_) {
|
||||
ping(ping$region.endpoint);
|
||||
}
|
||||
|
||||
List<RegionPingResult> list = Lists.newArrayList();
|
||||
|
||||
for(Ping.Region ping$region1 : p_87131_) {
|
||||
list.add(new RegionPingResult(ping$region1.name, ping(ping$region1.endpoint)));
|
||||
}
|
||||
|
||||
list.sort(Comparator.comparingInt(RegionPingResult::ping));
|
||||
return list;
|
||||
}
|
||||
|
||||
private static int ping(String p_87127_) {
|
||||
int i = 700;
|
||||
long j = 0L;
|
||||
Socket socket = null;
|
||||
|
||||
for(int k = 0; k < 5; ++k) {
|
||||
try {
|
||||
SocketAddress socketaddress = new InetSocketAddress(p_87127_, 80);
|
||||
socket = new Socket();
|
||||
long l = now();
|
||||
socket.connect(socketaddress, 700);
|
||||
j += now() - l;
|
||||
} catch (Exception exception) {
|
||||
j += 700L;
|
||||
} finally {
|
||||
IOUtils.closeQuietly(socket);
|
||||
}
|
||||
}
|
||||
|
||||
return (int)((double)j / 5.0D);
|
||||
}
|
||||
|
||||
private static long now() {
|
||||
return Util.getMillis();
|
||||
}
|
||||
|
||||
public static List<RegionPingResult> pingAllRegions() {
|
||||
return ping(Ping.Region.values());
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static enum Region {
|
||||
US_EAST_1("us-east-1", "ec2.us-east-1.amazonaws.com"),
|
||||
US_WEST_2("us-west-2", "ec2.us-west-2.amazonaws.com"),
|
||||
US_WEST_1("us-west-1", "ec2.us-west-1.amazonaws.com"),
|
||||
EU_WEST_1("eu-west-1", "ec2.eu-west-1.amazonaws.com"),
|
||||
AP_SOUTHEAST_1("ap-southeast-1", "ec2.ap-southeast-1.amazonaws.com"),
|
||||
AP_SOUTHEAST_2("ap-southeast-2", "ec2.ap-southeast-2.amazonaws.com"),
|
||||
AP_NORTHEAST_1("ap-northeast-1", "ec2.ap-northeast-1.amazonaws.com"),
|
||||
SA_EAST_1("sa-east-1", "ec2.sa-east-1.amazonaws.com");
|
||||
|
||||
final String name;
|
||||
final String endpoint;
|
||||
|
||||
private Region(String p_87148_, String p_87149_) {
|
||||
this.name = p_87148_;
|
||||
this.endpoint = p_87149_;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,497 @@
|
||||
package com.mojang.realmsclient.client;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.dto.BackupList;
|
||||
import com.mojang.realmsclient.dto.GuardedSerializer;
|
||||
import com.mojang.realmsclient.dto.Ops;
|
||||
import com.mojang.realmsclient.dto.PendingInvite;
|
||||
import com.mojang.realmsclient.dto.PendingInvitesList;
|
||||
import com.mojang.realmsclient.dto.PingResult;
|
||||
import com.mojang.realmsclient.dto.PlayerInfo;
|
||||
import com.mojang.realmsclient.dto.RealmsDescriptionDto;
|
||||
import com.mojang.realmsclient.dto.RealmsNews;
|
||||
import com.mojang.realmsclient.dto.RealmsNotification;
|
||||
import com.mojang.realmsclient.dto.RealmsServer;
|
||||
import com.mojang.realmsclient.dto.RealmsServerAddress;
|
||||
import com.mojang.realmsclient.dto.RealmsServerList;
|
||||
import com.mojang.realmsclient.dto.RealmsServerPlayerLists;
|
||||
import com.mojang.realmsclient.dto.RealmsWorldOptions;
|
||||
import com.mojang.realmsclient.dto.RealmsWorldResetDto;
|
||||
import com.mojang.realmsclient.dto.ServerActivityList;
|
||||
import com.mojang.realmsclient.dto.Subscription;
|
||||
import com.mojang.realmsclient.dto.UploadInfo;
|
||||
import com.mojang.realmsclient.dto.WorldDownload;
|
||||
import com.mojang.realmsclient.dto.WorldTemplatePaginatedList;
|
||||
import com.mojang.realmsclient.exception.RealmsHttpException;
|
||||
import com.mojang.realmsclient.exception.RealmsServiceException;
|
||||
import com.mojang.realmsclient.exception.RetryCallException;
|
||||
import com.mojang.realmsclient.util.WorldGenerationInfo;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.resources.language.I18n;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsClient {
|
||||
public static RealmsClient.Environment currentEnvironment = RealmsClient.Environment.PRODUCTION;
|
||||
private static boolean initialized;
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final String sessionId;
|
||||
private final String username;
|
||||
private final Minecraft minecraft;
|
||||
private static final String WORLDS_RESOURCE_PATH = "worlds";
|
||||
private static final String INVITES_RESOURCE_PATH = "invites";
|
||||
private static final String MCO_RESOURCE_PATH = "mco";
|
||||
private static final String SUBSCRIPTION_RESOURCE = "subscriptions";
|
||||
private static final String ACTIVITIES_RESOURCE = "activities";
|
||||
private static final String OPS_RESOURCE = "ops";
|
||||
private static final String REGIONS_RESOURCE = "regions/ping/stat";
|
||||
private static final String TRIALS_RESOURCE = "trial";
|
||||
private static final String NOTIFICATIONS_RESOURCE = "notifications";
|
||||
private static final String PATH_INITIALIZE = "/$WORLD_ID/initialize";
|
||||
private static final String PATH_GET_ACTIVTIES = "/$WORLD_ID";
|
||||
private static final String PATH_GET_LIVESTATS = "/liveplayerlist";
|
||||
private static final String PATH_GET_SUBSCRIPTION = "/$WORLD_ID";
|
||||
private static final String PATH_OP = "/$WORLD_ID/$PROFILE_UUID";
|
||||
private static final String PATH_PUT_INTO_MINIGAMES_MODE = "/minigames/$MINIGAME_ID/$WORLD_ID";
|
||||
private static final String PATH_AVAILABLE = "/available";
|
||||
private static final String PATH_TEMPLATES = "/templates/$WORLD_TYPE";
|
||||
private static final String PATH_WORLD_JOIN = "/v1/$ID/join/pc";
|
||||
private static final String PATH_WORLD_GET = "/$ID";
|
||||
private static final String PATH_WORLD_INVITES = "/$WORLD_ID";
|
||||
private static final String PATH_WORLD_UNINVITE = "/$WORLD_ID/invite/$UUID";
|
||||
private static final String PATH_PENDING_INVITES_COUNT = "/count/pending";
|
||||
private static final String PATH_PENDING_INVITES = "/pending";
|
||||
private static final String PATH_ACCEPT_INVITE = "/accept/$INVITATION_ID";
|
||||
private static final String PATH_REJECT_INVITE = "/reject/$INVITATION_ID";
|
||||
private static final String PATH_UNINVITE_MYSELF = "/$WORLD_ID";
|
||||
private static final String PATH_WORLD_UPDATE = "/$WORLD_ID";
|
||||
private static final String PATH_SLOT = "/$WORLD_ID/slot/$SLOT_ID";
|
||||
private static final String PATH_WORLD_OPEN = "/$WORLD_ID/open";
|
||||
private static final String PATH_WORLD_CLOSE = "/$WORLD_ID/close";
|
||||
private static final String PATH_WORLD_RESET = "/$WORLD_ID/reset";
|
||||
private static final String PATH_DELETE_WORLD = "/$WORLD_ID";
|
||||
private static final String PATH_WORLD_BACKUPS = "/$WORLD_ID/backups";
|
||||
private static final String PATH_WORLD_DOWNLOAD = "/$WORLD_ID/slot/$SLOT_ID/download";
|
||||
private static final String PATH_WORLD_UPLOAD = "/$WORLD_ID/backups/upload";
|
||||
private static final String PATH_CLIENT_COMPATIBLE = "/client/compatible";
|
||||
private static final String PATH_TOS_AGREED = "/tos/agreed";
|
||||
private static final String PATH_NEWS = "/v1/news";
|
||||
private static final String PATH_MARK_NOTIFICATIONS_SEEN = "/seen";
|
||||
private static final String PATH_DISMISS_NOTIFICATIONS = "/dismiss";
|
||||
private static final String PATH_STAGE_AVAILABLE = "/stageAvailable";
|
||||
private static final GuardedSerializer GSON = new GuardedSerializer();
|
||||
|
||||
public static RealmsClient create() {
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
return create(minecraft);
|
||||
}
|
||||
|
||||
public static RealmsClient create(Minecraft p_239152_) {
|
||||
String s = p_239152_.getUser().getName();
|
||||
String s1 = p_239152_.getUser().getSessionId();
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
Optional<String> optional = Optional.ofNullable(System.getenv("realms.environment")).or(() -> {
|
||||
return Optional.ofNullable(System.getProperty("realms.environment"));
|
||||
});
|
||||
optional.flatMap(RealmsClient.Environment::byName).ifPresent((p_289648_) -> {
|
||||
currentEnvironment = p_289648_;
|
||||
});
|
||||
}
|
||||
|
||||
return new RealmsClient(s1, s, p_239152_);
|
||||
}
|
||||
|
||||
public static void switchToStage() {
|
||||
currentEnvironment = RealmsClient.Environment.STAGE;
|
||||
}
|
||||
|
||||
public static void switchToProd() {
|
||||
currentEnvironment = RealmsClient.Environment.PRODUCTION;
|
||||
}
|
||||
|
||||
public static void switchToLocal() {
|
||||
currentEnvironment = RealmsClient.Environment.LOCAL;
|
||||
}
|
||||
|
||||
public RealmsClient(String p_87166_, String p_87167_, Minecraft p_87168_) {
|
||||
this.sessionId = p_87166_;
|
||||
this.username = p_87167_;
|
||||
this.minecraft = p_87168_;
|
||||
RealmsClientConfig.setProxy(p_87168_.getProxy());
|
||||
}
|
||||
|
||||
public RealmsServerList listWorlds() throws RealmsServiceException {
|
||||
String s = this.url("worlds");
|
||||
String s1 = this.execute(Request.get(s));
|
||||
return RealmsServerList.parse(s1);
|
||||
}
|
||||
|
||||
public List<RealmsNotification> getNotifications() throws RealmsServiceException {
|
||||
String s = this.url("notifications");
|
||||
String s1 = this.execute(Request.get(s));
|
||||
List<RealmsNotification> list = RealmsNotification.parseList(s1);
|
||||
return list.size() > 1 ? List.of(list.get(0)) : list;
|
||||
}
|
||||
|
||||
private static JsonArray uuidListToJsonArray(List<UUID> p_275393_) {
|
||||
JsonArray jsonarray = new JsonArray();
|
||||
|
||||
for(UUID uuid : p_275393_) {
|
||||
if (uuid != null) {
|
||||
jsonarray.add(uuid.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return jsonarray;
|
||||
}
|
||||
|
||||
public void notificationsSeen(List<UUID> p_275212_) throws RealmsServiceException {
|
||||
String s = this.url("notifications/seen");
|
||||
this.execute(Request.post(s, GSON.toJson(uuidListToJsonArray(p_275212_))));
|
||||
}
|
||||
|
||||
public void notificationsDismiss(List<UUID> p_275407_) throws RealmsServiceException {
|
||||
String s = this.url("notifications/dismiss");
|
||||
this.execute(Request.post(s, GSON.toJson(uuidListToJsonArray(p_275407_))));
|
||||
}
|
||||
|
||||
public RealmsServer getOwnWorld(long p_87175_) throws RealmsServiceException {
|
||||
String s = this.url("worlds" + "/$ID".replace("$ID", String.valueOf(p_87175_)));
|
||||
String s1 = this.execute(Request.get(s));
|
||||
return RealmsServer.parse(s1);
|
||||
}
|
||||
|
||||
public ServerActivityList getActivity(long p_167279_) throws RealmsServiceException {
|
||||
String s = this.url("activities" + "/$WORLD_ID".replace("$WORLD_ID", String.valueOf(p_167279_)));
|
||||
String s1 = this.execute(Request.get(s));
|
||||
return ServerActivityList.parse(s1);
|
||||
}
|
||||
|
||||
public RealmsServerPlayerLists getLiveStats() throws RealmsServiceException {
|
||||
String s = this.url("activities/liveplayerlist");
|
||||
String s1 = this.execute(Request.get(s));
|
||||
return RealmsServerPlayerLists.parse(s1);
|
||||
}
|
||||
|
||||
public RealmsServerAddress join(long p_87208_) throws RealmsServiceException {
|
||||
String s = this.url("worlds" + "/v1/$ID/join/pc".replace("$ID", "" + p_87208_));
|
||||
String s1 = this.execute(Request.get(s, 5000, 30000));
|
||||
return RealmsServerAddress.parse(s1);
|
||||
}
|
||||
|
||||
public void initializeWorld(long p_87192_, String p_87193_, String p_87194_) throws RealmsServiceException {
|
||||
RealmsDescriptionDto realmsdescriptiondto = new RealmsDescriptionDto(p_87193_, p_87194_);
|
||||
String s = this.url("worlds" + "/$WORLD_ID/initialize".replace("$WORLD_ID", String.valueOf(p_87192_)));
|
||||
String s1 = GSON.toJson(realmsdescriptiondto);
|
||||
this.execute(Request.post(s, s1, 5000, 10000));
|
||||
}
|
||||
|
||||
public Boolean mcoEnabled() throws RealmsServiceException {
|
||||
String s = this.url("mco/available");
|
||||
String s1 = this.execute(Request.get(s));
|
||||
return Boolean.valueOf(s1);
|
||||
}
|
||||
|
||||
public Boolean stageAvailable() throws RealmsServiceException {
|
||||
String s = this.url("mco/stageAvailable");
|
||||
String s1 = this.execute(Request.get(s));
|
||||
return Boolean.valueOf(s1);
|
||||
}
|
||||
|
||||
public RealmsClient.CompatibleVersionResponse clientCompatible() throws RealmsServiceException {
|
||||
String s = this.url("mco/client/compatible");
|
||||
String s1 = this.execute(Request.get(s));
|
||||
|
||||
try {
|
||||
return RealmsClient.CompatibleVersionResponse.valueOf(s1);
|
||||
} catch (IllegalArgumentException illegalargumentexception) {
|
||||
throw new RealmsServiceException(500, "Could not check compatible version, got response: " + s1);
|
||||
}
|
||||
}
|
||||
|
||||
public void uninvite(long p_87184_, String p_87185_) throws RealmsServiceException {
|
||||
String s = this.url("invites" + "/$WORLD_ID/invite/$UUID".replace("$WORLD_ID", String.valueOf(p_87184_)).replace("$UUID", p_87185_));
|
||||
this.execute(Request.delete(s));
|
||||
}
|
||||
|
||||
public void uninviteMyselfFrom(long p_87223_) throws RealmsServiceException {
|
||||
String s = this.url("invites" + "/$WORLD_ID".replace("$WORLD_ID", String.valueOf(p_87223_)));
|
||||
this.execute(Request.delete(s));
|
||||
}
|
||||
|
||||
public RealmsServer invite(long p_87213_, String p_87214_) throws RealmsServiceException {
|
||||
PlayerInfo playerinfo = new PlayerInfo();
|
||||
playerinfo.setName(p_87214_);
|
||||
String s = this.url("invites" + "/$WORLD_ID".replace("$WORLD_ID", String.valueOf(p_87213_)));
|
||||
String s1 = this.execute(Request.post(s, GSON.toJson(playerinfo)));
|
||||
return RealmsServer.parse(s1);
|
||||
}
|
||||
|
||||
public BackupList backupsFor(long p_87231_) throws RealmsServiceException {
|
||||
String s = this.url("worlds" + "/$WORLD_ID/backups".replace("$WORLD_ID", String.valueOf(p_87231_)));
|
||||
String s1 = this.execute(Request.get(s));
|
||||
return BackupList.parse(s1);
|
||||
}
|
||||
|
||||
public void update(long p_87216_, String p_87217_, String p_87218_) throws RealmsServiceException {
|
||||
RealmsDescriptionDto realmsdescriptiondto = new RealmsDescriptionDto(p_87217_, p_87218_);
|
||||
String s = this.url("worlds" + "/$WORLD_ID".replace("$WORLD_ID", String.valueOf(p_87216_)));
|
||||
this.execute(Request.post(s, GSON.toJson(realmsdescriptiondto)));
|
||||
}
|
||||
|
||||
public void updateSlot(long p_87180_, int p_87181_, RealmsWorldOptions p_87182_) throws RealmsServiceException {
|
||||
String s = this.url("worlds" + "/$WORLD_ID/slot/$SLOT_ID".replace("$WORLD_ID", String.valueOf(p_87180_)).replace("$SLOT_ID", String.valueOf(p_87181_)));
|
||||
String s1 = p_87182_.toJson();
|
||||
this.execute(Request.post(s, s1));
|
||||
}
|
||||
|
||||
public boolean switchSlot(long p_87177_, int p_87178_) throws RealmsServiceException {
|
||||
String s = this.url("worlds" + "/$WORLD_ID/slot/$SLOT_ID".replace("$WORLD_ID", String.valueOf(p_87177_)).replace("$SLOT_ID", String.valueOf(p_87178_)));
|
||||
String s1 = this.execute(Request.put(s, ""));
|
||||
return Boolean.valueOf(s1);
|
||||
}
|
||||
|
||||
public void restoreWorld(long p_87225_, String p_87226_) throws RealmsServiceException {
|
||||
String s = this.url("worlds" + "/$WORLD_ID/backups".replace("$WORLD_ID", String.valueOf(p_87225_)), "backupId=" + p_87226_);
|
||||
this.execute(Request.put(s, "", 40000, 600000));
|
||||
}
|
||||
|
||||
public WorldTemplatePaginatedList fetchWorldTemplates(int p_87171_, int p_87172_, RealmsServer.WorldType p_87173_) throws RealmsServiceException {
|
||||
String s = this.url("worlds" + "/templates/$WORLD_TYPE".replace("$WORLD_TYPE", p_87173_.toString()), String.format(Locale.ROOT, "page=%d&pageSize=%d", p_87171_, p_87172_));
|
||||
String s1 = this.execute(Request.get(s));
|
||||
return WorldTemplatePaginatedList.parse(s1);
|
||||
}
|
||||
|
||||
public Boolean putIntoMinigameMode(long p_87233_, String p_87234_) throws RealmsServiceException {
|
||||
String s = "/minigames/$MINIGAME_ID/$WORLD_ID".replace("$MINIGAME_ID", p_87234_).replace("$WORLD_ID", String.valueOf(p_87233_));
|
||||
String s1 = this.url("worlds" + s);
|
||||
return Boolean.valueOf(this.execute(Request.put(s1, "")));
|
||||
}
|
||||
|
||||
public Ops op(long p_87239_, String p_87240_) throws RealmsServiceException {
|
||||
String s = "/$WORLD_ID/$PROFILE_UUID".replace("$WORLD_ID", String.valueOf(p_87239_)).replace("$PROFILE_UUID", p_87240_);
|
||||
String s1 = this.url("ops" + s);
|
||||
return Ops.parse(this.execute(Request.post(s1, "")));
|
||||
}
|
||||
|
||||
public Ops deop(long p_87245_, String p_87246_) throws RealmsServiceException {
|
||||
String s = "/$WORLD_ID/$PROFILE_UUID".replace("$WORLD_ID", String.valueOf(p_87245_)).replace("$PROFILE_UUID", p_87246_);
|
||||
String s1 = this.url("ops" + s);
|
||||
return Ops.parse(this.execute(Request.delete(s1)));
|
||||
}
|
||||
|
||||
public Boolean open(long p_87237_) throws RealmsServiceException {
|
||||
String s = this.url("worlds" + "/$WORLD_ID/open".replace("$WORLD_ID", String.valueOf(p_87237_)));
|
||||
String s1 = this.execute(Request.put(s, ""));
|
||||
return Boolean.valueOf(s1);
|
||||
}
|
||||
|
||||
public Boolean close(long p_87243_) throws RealmsServiceException {
|
||||
String s = this.url("worlds" + "/$WORLD_ID/close".replace("$WORLD_ID", String.valueOf(p_87243_)));
|
||||
String s1 = this.execute(Request.put(s, ""));
|
||||
return Boolean.valueOf(s1);
|
||||
}
|
||||
|
||||
public Boolean resetWorldWithSeed(long p_167276_, WorldGenerationInfo p_167277_) throws RealmsServiceException {
|
||||
RealmsWorldResetDto realmsworldresetdto = new RealmsWorldResetDto(p_167277_.getSeed(), -1L, p_167277_.getLevelType().getDtoIndex(), p_167277_.shouldGenerateStructures());
|
||||
String s = this.url("worlds" + "/$WORLD_ID/reset".replace("$WORLD_ID", String.valueOf(p_167276_)));
|
||||
String s1 = this.execute(Request.post(s, GSON.toJson(realmsworldresetdto), 30000, 80000));
|
||||
return Boolean.valueOf(s1);
|
||||
}
|
||||
|
||||
public Boolean resetWorldWithTemplate(long p_87251_, String p_87252_) throws RealmsServiceException {
|
||||
RealmsWorldResetDto realmsworldresetdto = new RealmsWorldResetDto((String)null, Long.valueOf(p_87252_), -1, false);
|
||||
String s = this.url("worlds" + "/$WORLD_ID/reset".replace("$WORLD_ID", String.valueOf(p_87251_)));
|
||||
String s1 = this.execute(Request.post(s, GSON.toJson(realmsworldresetdto), 30000, 80000));
|
||||
return Boolean.valueOf(s1);
|
||||
}
|
||||
|
||||
public Subscription subscriptionFor(long p_87249_) throws RealmsServiceException {
|
||||
String s = this.url("subscriptions" + "/$WORLD_ID".replace("$WORLD_ID", String.valueOf(p_87249_)));
|
||||
String s1 = this.execute(Request.get(s));
|
||||
return Subscription.parse(s1);
|
||||
}
|
||||
|
||||
public int pendingInvitesCount() throws RealmsServiceException {
|
||||
return this.pendingInvites().pendingInvites.size();
|
||||
}
|
||||
|
||||
public PendingInvitesList pendingInvites() throws RealmsServiceException {
|
||||
String s = this.url("invites/pending");
|
||||
String s1 = this.execute(Request.get(s));
|
||||
PendingInvitesList pendinginviteslist = PendingInvitesList.parse(s1);
|
||||
pendinginviteslist.pendingInvites.removeIf(this::isBlocked);
|
||||
return pendinginviteslist;
|
||||
}
|
||||
|
||||
private boolean isBlocked(PendingInvite p_87198_) {
|
||||
try {
|
||||
UUID uuid = UUID.fromString(p_87198_.worldOwnerUuid);
|
||||
return this.minecraft.getPlayerSocialManager().isBlocked(uuid);
|
||||
} catch (IllegalArgumentException illegalargumentexception) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void acceptInvitation(String p_87202_) throws RealmsServiceException {
|
||||
String s = this.url("invites" + "/accept/$INVITATION_ID".replace("$INVITATION_ID", p_87202_));
|
||||
this.execute(Request.put(s, ""));
|
||||
}
|
||||
|
||||
public WorldDownload requestDownloadInfo(long p_87210_, int p_87211_) throws RealmsServiceException {
|
||||
String s = this.url("worlds" + "/$WORLD_ID/slot/$SLOT_ID/download".replace("$WORLD_ID", String.valueOf(p_87210_)).replace("$SLOT_ID", String.valueOf(p_87211_)));
|
||||
String s1 = this.execute(Request.get(s));
|
||||
return WorldDownload.parse(s1);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public UploadInfo requestUploadInfo(long p_87257_, @Nullable String p_87258_) throws RealmsServiceException {
|
||||
String s = this.url("worlds" + "/$WORLD_ID/backups/upload".replace("$WORLD_ID", String.valueOf(p_87257_)));
|
||||
return UploadInfo.parse(this.execute(Request.put(s, UploadInfo.createRequest(p_87258_))));
|
||||
}
|
||||
|
||||
public void rejectInvitation(String p_87220_) throws RealmsServiceException {
|
||||
String s = this.url("invites" + "/reject/$INVITATION_ID".replace("$INVITATION_ID", p_87220_));
|
||||
this.execute(Request.put(s, ""));
|
||||
}
|
||||
|
||||
public void agreeToTos() throws RealmsServiceException {
|
||||
String s = this.url("mco/tos/agreed");
|
||||
this.execute(Request.post(s, ""));
|
||||
}
|
||||
|
||||
public RealmsNews getNews() throws RealmsServiceException {
|
||||
String s = this.url("mco/v1/news");
|
||||
String s1 = this.execute(Request.get(s, 5000, 10000));
|
||||
return RealmsNews.parse(s1);
|
||||
}
|
||||
|
||||
public void sendPingResults(PingResult p_87200_) throws RealmsServiceException {
|
||||
String s = this.url("regions/ping/stat");
|
||||
this.execute(Request.post(s, GSON.toJson(p_87200_)));
|
||||
}
|
||||
|
||||
public Boolean trialAvailable() throws RealmsServiceException {
|
||||
String s = this.url("trial");
|
||||
String s1 = this.execute(Request.get(s));
|
||||
return Boolean.valueOf(s1);
|
||||
}
|
||||
|
||||
public void deleteWorld(long p_87255_) throws RealmsServiceException {
|
||||
String s = this.url("worlds" + "/$WORLD_ID".replace("$WORLD_ID", String.valueOf(p_87255_)));
|
||||
this.execute(Request.delete(s));
|
||||
}
|
||||
|
||||
private String url(String p_87228_) {
|
||||
return this.url(p_87228_, (String)null);
|
||||
}
|
||||
|
||||
private String url(String p_87204_, @Nullable String p_87205_) {
|
||||
try {
|
||||
return (new URI(currentEnvironment.protocol, currentEnvironment.baseUrl, "/" + p_87204_, p_87205_, (String)null)).toASCIIString();
|
||||
} catch (URISyntaxException urisyntaxexception) {
|
||||
throw new IllegalArgumentException(p_87204_, urisyntaxexception);
|
||||
}
|
||||
}
|
||||
|
||||
private String execute(Request<?> p_87196_) throws RealmsServiceException {
|
||||
p_87196_.cookie("sid", this.sessionId);
|
||||
p_87196_.cookie("user", this.username);
|
||||
p_87196_.cookie("version", SharedConstants.getCurrentVersion().getName());
|
||||
|
||||
try {
|
||||
int i = p_87196_.responseCode();
|
||||
if (i != 503 && i != 277) {
|
||||
String s1 = p_87196_.text();
|
||||
if (i >= 200 && i < 300) {
|
||||
return s1;
|
||||
} else if (i == 401) {
|
||||
String s2 = p_87196_.getHeader("WWW-Authenticate");
|
||||
LOGGER.info("Could not authorize you against Realms server: {}", (Object)s2);
|
||||
throw new RealmsServiceException(i, s2);
|
||||
} else {
|
||||
RealmsError realmserror = RealmsError.parse(s1);
|
||||
if (realmserror != null) {
|
||||
LOGGER.error("Realms http code: {} - error code: {} - message: {} - raw body: {}", i, realmserror.getErrorCode(), realmserror.getErrorMessage(), s1);
|
||||
throw new RealmsServiceException(i, s1, realmserror);
|
||||
} else {
|
||||
LOGGER.error("Realms http code: {} - raw body (message failed to parse): {}", i, s1);
|
||||
String s = getHttpCodeDescription(i);
|
||||
throw new RealmsServiceException(i, s);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int j = p_87196_.getRetryAfterHeader();
|
||||
throw new RetryCallException(j, i);
|
||||
}
|
||||
} catch (RealmsHttpException realmshttpexception) {
|
||||
throw new RealmsServiceException(500, "Could not connect to Realms: " + realmshttpexception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static String getHttpCodeDescription(int p_200937_) {
|
||||
String s;
|
||||
switch (p_200937_) {
|
||||
case 429:
|
||||
s = I18n.get("mco.errorMessage.serviceBusy");
|
||||
break;
|
||||
default:
|
||||
s = "Unknown error";
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum CompatibleVersionResponse {
|
||||
COMPATIBLE,
|
||||
OUTDATED,
|
||||
OTHER;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum Environment {
|
||||
PRODUCTION("pc.realms.minecraft.net", "https"),
|
||||
STAGE("pc-stage.realms.minecraft.net", "https"),
|
||||
LOCAL("localhost:8080", "http");
|
||||
|
||||
public String baseUrl;
|
||||
public String protocol;
|
||||
|
||||
private Environment(String p_87286_, String p_87287_) {
|
||||
this.baseUrl = p_87286_;
|
||||
this.protocol = p_87287_;
|
||||
}
|
||||
|
||||
public static Optional<RealmsClient.Environment> byName(String p_289688_) {
|
||||
Optional optional;
|
||||
switch (p_289688_.toLowerCase(Locale.ROOT)) {
|
||||
case "production":
|
||||
optional = Optional.of(PRODUCTION);
|
||||
break;
|
||||
case "local":
|
||||
optional = Optional.of(LOCAL);
|
||||
break;
|
||||
case "stage":
|
||||
optional = Optional.of(STAGE);
|
||||
break;
|
||||
default:
|
||||
optional = Optional.empty();
|
||||
}
|
||||
|
||||
return optional;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.mojang.realmsclient.client;
|
||||
|
||||
import java.net.Proxy;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsClientConfig {
|
||||
@Nullable
|
||||
private static Proxy proxy;
|
||||
|
||||
@Nullable
|
||||
public static Proxy getProxy() {
|
||||
return proxy;
|
||||
}
|
||||
|
||||
public static void setProxy(Proxy p_87294_) {
|
||||
if (proxy == null) {
|
||||
proxy = p_87294_;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.mojang.realmsclient.client;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.util.JsonUtils;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsError {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final String errorMessage;
|
||||
private final int errorCode;
|
||||
|
||||
private RealmsError(String p_87300_, int p_87301_) {
|
||||
this.errorMessage = p_87300_;
|
||||
this.errorCode = p_87301_;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static RealmsError parse(String p_87304_) {
|
||||
if (Strings.isNullOrEmpty(p_87304_)) {
|
||||
return null;
|
||||
} else {
|
||||
try {
|
||||
JsonObject jsonobject = JsonParser.parseString(p_87304_).getAsJsonObject();
|
||||
String s = JsonUtils.getStringOr("errorMsg", jsonobject, "");
|
||||
int i = JsonUtils.getIntOr("errorCode", jsonobject, -1);
|
||||
return new RealmsError(s, i);
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Could not parse RealmsError: {}", (Object)exception.getMessage());
|
||||
LOGGER.error("The error was: {}", (Object)p_87304_);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getErrorMessage() {
|
||||
return this.errorMessage;
|
||||
}
|
||||
|
||||
public int getErrorCode() {
|
||||
return this.errorCode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
package com.mojang.realmsclient.client;
|
||||
|
||||
import com.mojang.realmsclient.exception.RealmsHttpException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public abstract class Request<T extends Request<T>> {
|
||||
protected HttpURLConnection connection;
|
||||
private boolean connected;
|
||||
protected String url;
|
||||
private static final int DEFAULT_READ_TIMEOUT = 60000;
|
||||
private static final int DEFAULT_CONNECT_TIMEOUT = 5000;
|
||||
|
||||
public Request(String p_87310_, int p_87311_, int p_87312_) {
|
||||
try {
|
||||
this.url = p_87310_;
|
||||
Proxy proxy = RealmsClientConfig.getProxy();
|
||||
if (proxy != null) {
|
||||
this.connection = (HttpURLConnection)(new URL(p_87310_)).openConnection(proxy);
|
||||
} else {
|
||||
this.connection = (HttpURLConnection)(new URL(p_87310_)).openConnection();
|
||||
}
|
||||
|
||||
this.connection.setConnectTimeout(p_87311_);
|
||||
this.connection.setReadTimeout(p_87312_);
|
||||
} catch (MalformedURLException malformedurlexception) {
|
||||
throw new RealmsHttpException(malformedurlexception.getMessage(), malformedurlexception);
|
||||
} catch (IOException ioexception) {
|
||||
throw new RealmsHttpException(ioexception.getMessage(), ioexception);
|
||||
}
|
||||
}
|
||||
|
||||
public void cookie(String p_87323_, String p_87324_) {
|
||||
cookie(this.connection, p_87323_, p_87324_);
|
||||
}
|
||||
|
||||
public static void cookie(HttpURLConnection p_87336_, String p_87337_, String p_87338_) {
|
||||
String s = p_87336_.getRequestProperty("Cookie");
|
||||
if (s == null) {
|
||||
p_87336_.setRequestProperty("Cookie", p_87337_ + "=" + p_87338_);
|
||||
} else {
|
||||
p_87336_.setRequestProperty("Cookie", s + ";" + p_87337_ + "=" + p_87338_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public T header(String p_167286_, String p_167287_) {
|
||||
this.connection.addRequestProperty(p_167286_, p_167287_);
|
||||
return (T)this;
|
||||
}
|
||||
|
||||
public int getRetryAfterHeader() {
|
||||
return getRetryAfterHeader(this.connection);
|
||||
}
|
||||
|
||||
public static int getRetryAfterHeader(HttpURLConnection p_87331_) {
|
||||
String s = p_87331_.getHeaderField("Retry-After");
|
||||
|
||||
try {
|
||||
return Integer.valueOf(s);
|
||||
} catch (Exception exception) {
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
public int responseCode() {
|
||||
try {
|
||||
this.connect();
|
||||
return this.connection.getResponseCode();
|
||||
} catch (Exception exception) {
|
||||
throw new RealmsHttpException(exception.getMessage(), exception);
|
||||
}
|
||||
}
|
||||
|
||||
public String text() {
|
||||
try {
|
||||
this.connect();
|
||||
String s;
|
||||
if (this.responseCode() >= 400) {
|
||||
s = this.read(this.connection.getErrorStream());
|
||||
} else {
|
||||
s = this.read(this.connection.getInputStream());
|
||||
}
|
||||
|
||||
this.dispose();
|
||||
return s;
|
||||
} catch (IOException ioexception) {
|
||||
throw new RealmsHttpException(ioexception.getMessage(), ioexception);
|
||||
}
|
||||
}
|
||||
|
||||
private String read(@Nullable InputStream p_87315_) throws IOException {
|
||||
if (p_87315_ == null) {
|
||||
return "";
|
||||
} else {
|
||||
InputStreamReader inputstreamreader = new InputStreamReader(p_87315_, StandardCharsets.UTF_8);
|
||||
StringBuilder stringbuilder = new StringBuilder();
|
||||
|
||||
for(int i = inputstreamreader.read(); i != -1; i = inputstreamreader.read()) {
|
||||
stringbuilder.append((char)i);
|
||||
}
|
||||
|
||||
return stringbuilder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private void dispose() {
|
||||
byte[] abyte = new byte[1024];
|
||||
|
||||
try {
|
||||
InputStream inputstream = this.connection.getInputStream();
|
||||
|
||||
while(inputstream.read(abyte) > 0) {
|
||||
}
|
||||
|
||||
inputstream.close();
|
||||
return;
|
||||
} catch (Exception exception) {
|
||||
try {
|
||||
InputStream inputstream1 = this.connection.getErrorStream();
|
||||
if (inputstream1 != null) {
|
||||
while(inputstream1.read(abyte) > 0) {
|
||||
}
|
||||
|
||||
inputstream1.close();
|
||||
return;
|
||||
}
|
||||
} catch (IOException ioexception) {
|
||||
return;
|
||||
}
|
||||
} finally {
|
||||
if (this.connection != null) {
|
||||
this.connection.disconnect();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected T connect() {
|
||||
if (this.connected) {
|
||||
return (T)this;
|
||||
} else {
|
||||
T t = this.doConnect();
|
||||
this.connected = true;
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract T doConnect();
|
||||
|
||||
public static Request<?> get(String p_87317_) {
|
||||
return new Request.Get(p_87317_, 5000, 60000);
|
||||
}
|
||||
|
||||
public static Request<?> get(String p_87319_, int p_87320_, int p_87321_) {
|
||||
return new Request.Get(p_87319_, p_87320_, p_87321_);
|
||||
}
|
||||
|
||||
public static Request<?> post(String p_87343_, String p_87344_) {
|
||||
return new Request.Post(p_87343_, p_87344_, 5000, 60000);
|
||||
}
|
||||
|
||||
public static Request<?> post(String p_87326_, String p_87327_, int p_87328_, int p_87329_) {
|
||||
return new Request.Post(p_87326_, p_87327_, p_87328_, p_87329_);
|
||||
}
|
||||
|
||||
public static Request<?> delete(String p_87341_) {
|
||||
return new Request.Delete(p_87341_, 5000, 60000);
|
||||
}
|
||||
|
||||
public static Request<?> put(String p_87354_, String p_87355_) {
|
||||
return new Request.Put(p_87354_, p_87355_, 5000, 60000);
|
||||
}
|
||||
|
||||
public static Request<?> put(String p_87346_, String p_87347_, int p_87348_, int p_87349_) {
|
||||
return new Request.Put(p_87346_, p_87347_, p_87348_, p_87349_);
|
||||
}
|
||||
|
||||
public String getHeader(String p_87352_) {
|
||||
return getHeader(this.connection, p_87352_);
|
||||
}
|
||||
|
||||
public static String getHeader(HttpURLConnection p_87333_, String p_87334_) {
|
||||
try {
|
||||
return p_87333_.getHeaderField(p_87334_);
|
||||
} catch (Exception exception) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class Delete extends Request<Request.Delete> {
|
||||
public Delete(String p_87359_, int p_87360_, int p_87361_) {
|
||||
super(p_87359_, p_87360_, p_87361_);
|
||||
}
|
||||
|
||||
public Request.Delete doConnect() {
|
||||
try {
|
||||
this.connection.setDoOutput(true);
|
||||
this.connection.setRequestMethod("DELETE");
|
||||
this.connection.connect();
|
||||
return this;
|
||||
} catch (Exception exception) {
|
||||
throw new RealmsHttpException(exception.getMessage(), exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class Get extends Request<Request.Get> {
|
||||
public Get(String p_87365_, int p_87366_, int p_87367_) {
|
||||
super(p_87365_, p_87366_, p_87367_);
|
||||
}
|
||||
|
||||
public Request.Get doConnect() {
|
||||
try {
|
||||
this.connection.setDoInput(true);
|
||||
this.connection.setDoOutput(true);
|
||||
this.connection.setUseCaches(false);
|
||||
this.connection.setRequestMethod("GET");
|
||||
return this;
|
||||
} catch (Exception exception) {
|
||||
throw new RealmsHttpException(exception.getMessage(), exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class Post extends Request<Request.Post> {
|
||||
private final String content;
|
||||
|
||||
public Post(String p_87372_, String p_87373_, int p_87374_, int p_87375_) {
|
||||
super(p_87372_, p_87374_, p_87375_);
|
||||
this.content = p_87373_;
|
||||
}
|
||||
|
||||
public Request.Post doConnect() {
|
||||
try {
|
||||
if (this.content != null) {
|
||||
this.connection.setRequestProperty("Content-Type", "application/json; charset=utf-8");
|
||||
}
|
||||
|
||||
this.connection.setDoInput(true);
|
||||
this.connection.setDoOutput(true);
|
||||
this.connection.setUseCaches(false);
|
||||
this.connection.setRequestMethod("POST");
|
||||
OutputStream outputstream = this.connection.getOutputStream();
|
||||
OutputStreamWriter outputstreamwriter = new OutputStreamWriter(outputstream, "UTF-8");
|
||||
outputstreamwriter.write(this.content);
|
||||
outputstreamwriter.close();
|
||||
outputstream.flush();
|
||||
return this;
|
||||
} catch (Exception exception) {
|
||||
throw new RealmsHttpException(exception.getMessage(), exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class Put extends Request<Request.Put> {
|
||||
private final String content;
|
||||
|
||||
public Put(String p_87380_, String p_87381_, int p_87382_, int p_87383_) {
|
||||
super(p_87380_, p_87382_, p_87383_);
|
||||
this.content = p_87381_;
|
||||
}
|
||||
|
||||
public Request.Put doConnect() {
|
||||
try {
|
||||
if (this.content != null) {
|
||||
this.connection.setRequestProperty("Content-Type", "application/json; charset=utf-8");
|
||||
}
|
||||
|
||||
this.connection.setDoOutput(true);
|
||||
this.connection.setDoInput(true);
|
||||
this.connection.setRequestMethod("PUT");
|
||||
OutputStream outputstream = this.connection.getOutputStream();
|
||||
OutputStreamWriter outputstreamwriter = new OutputStreamWriter(outputstream, "UTF-8");
|
||||
outputstreamwriter.write(this.content);
|
||||
outputstreamwriter.close();
|
||||
outputstream.flush();
|
||||
return this;
|
||||
} catch (Exception exception) {
|
||||
throw new RealmsHttpException(exception.getMessage(), exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.mojang.realmsclient.client;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class UploadStatus {
|
||||
public volatile long bytesWritten;
|
||||
public volatile long totalBytes;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
package com.mojang.realmsclient.client;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraft.FieldsAreNonnullByDefault;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user