Update #34 - Add dynamic lights, fix vanilla world seeds

This commit is contained in:
lax1dude
2024-06-08 16:02:29 -07:00
parent 591f724d23
commit 6f7f4ed46b
96 changed files with 2400 additions and 193 deletions

View File

@ -3,7 +3,7 @@ package net.lax1dude.eaglercraft.v1_8;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -25,19 +25,46 @@ public class EaglercraftRandom {
private static final double DOUBLE_UNIT = 0x1.0p-53;
private long seed = 69;
private static int yee = 0;
private final boolean enableScramble;
public EaglercraftRandom() {
this(PlatformRuntime.randomSeed());
}
public EaglercraftRandom(long seed) {
this(seed, true);
}
public EaglercraftRandom(boolean scramble) {
this(PlatformRuntime.randomSeed(), scramble);
}
/**
* Older versions of EaglercraftX (and Eaglercraft) are missing the
* "initialScramble" function from their setSeed function, which was what caused
* world generation to not match vanilla. The "enableScramble" boolean is used
* when players play on an old world created before the bug was fixed.
*/
public EaglercraftRandom(long seed, boolean scramble) {
enableScramble = scramble;
setSeed(seed);
}
private static long initialScramble(long seed) {
return (seed ^ multiplier) & mask;
}
public void setSeed(long yeed) {
seed = yeed;
if(enableScramble) {
seed = initialScramble(yeed);
}else {
seed = yeed;
}
haveNextNextGaussian = true;
}
public boolean isScramble() {
return enableScramble;
}
protected int next(int bits) {

View File

@ -10,7 +10,7 @@ public class EaglercraftVersion {
/// Customize these to fit your fork:
public static final String projectForkName = "EaglercraftX";
public static final String projectForkVersion = "u32";
public static final String projectForkVersion = "u34";
public static final String projectForkVendor = "lax1dude";
public static final String projectForkURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8";
@ -20,7 +20,7 @@ public class EaglercraftVersion {
public static final String projectOriginName = "EaglercraftX";
public static final String projectOriginAuthor = "lax1dude";
public static final String projectOriginRevision = "1.8";
public static final String projectOriginVersion = "u32";
public static final String projectOriginVersion = "u34";
public static final String projectOriginURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8"; // rest in peace
@ -31,7 +31,7 @@ public class EaglercraftVersion {
public static final boolean enableUpdateService = true;
public static final String updateBundlePackageName = "net.lax1dude.eaglercraft.v1_8.client";
public static final int updateBundlePackageVersionInt = 32;
public static final int updateBundlePackageVersionInt = 34;
public static final String updateLatestLocalStorageKey = "latestUpdate_" + updateBundlePackageName;

View File

@ -19,6 +19,7 @@ import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.lax1dude.eaglercraft.v1_8.opengl.StreamBuffer.StreamBufferInstance;
import net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights.DynamicLightsStateManager;
import net.lax1dude.eaglercraft.v1_8.vector.Matrix4f;
import net.lax1dude.eaglercraft.v1_8.vector.Vector4f;
import net.minecraft.util.MathHelper;
@ -904,7 +905,9 @@ public class FixedFunctionPipeline {
_wglUniform3f(stateLightingAmbientUniform3f, r, g, b);
}
}
}
if(stateEnableMCLighting || DynamicLightsStateManager.isInDynamicLightsPass()) {
if(!stateHasAttribNormal) {
serial = GlStateManager.stateNormalSerial;
if(stateNormalSerial != serial) {

View File

@ -808,6 +808,22 @@ public class GlStateManager {
}
}
public static final void getFloat(int pname, FloatBuffer params) {
switch(pname) {
case GL_MODELVIEW_MATRIX:
modelMatrixStack[modelMatrixStackPointer].store(params);
break;
case GL_PROJECTION_MATRIX:
projectionMatrixStack[projectionMatrixStackPointer].store(params);
break;
case GL_TEXTURE_MATRIX:
textureMatrixStack[activeTexture][textureMatrixStackPointer[activeTexture]].store(params);
break;
default:
throw new UnsupportedOperationException("glGetFloat can only be used to retrieve matricies!");
}
}
public static final void ortho(double left, double right, double bottom, double top, double zNear, double zFar) {
Matrix4f matrix;
switch(stateMatrixMode) {

View File

@ -49,8 +49,8 @@ public class InstancedParticleRenderer {
private static IUniformGL u_matrixTransform = null;
private static FloatBuffer matrixCopyBuffer = null;
private static IUniformGL u_texCoordSize2f_particleSize1f = null;
private static IUniformGL u_transformParam_1_2_3_4_f = null;
private static IUniformGL u_transformParam_5_f = null;
private static IUniformGL u_transformParam_1_2_5_f = null;
private static IUniformGL u_transformParam_3_4_f = null;
private static IUniformGL u_color4f = null;
private static IBufferArrayGL vertexArray = null;
@ -154,8 +154,8 @@ public class InstancedParticleRenderer {
u_matrixTransform = _wglGetUniformLocation(shaderProgram, "u_matrixTransform");
u_texCoordSize2f_particleSize1f = _wglGetUniformLocation(shaderProgram, "u_texCoordSize2f_particleSize1f");
u_transformParam_1_2_3_4_f = _wglGetUniformLocation(shaderProgram, "u_transformParam_1_2_3_4_f");
u_transformParam_5_f = _wglGetUniformLocation(shaderProgram, "u_transformParam_5_f");
u_transformParam_1_2_5_f = _wglGetUniformLocation(shaderProgram, "u_transformParam_1_2_5_f");
u_transformParam_3_4_f = _wglGetUniformLocation(shaderProgram, "u_transformParam_3_4_f");
u_color4f = _wglGetUniformLocation(shaderProgram, "u_color4f");
_wglUniform1i(_wglGetUniformLocation(shaderProgram, "u_inputTexture"), 0);
@ -260,17 +260,17 @@ public class InstancedParticleRenderer {
}
if (transformParam1 != stateTransformParam1 || transformParam2 != stateTransformParam2
|| transformParam3 != stateTransformParam3 || transformParam4 != stateTransformParam4) {
_wglUniform4f(u_transformParam_1_2_3_4_f, transformParam1, transformParam2, transformParam3, transformParam4);
|| transformParam5 != stateTransformParam5) {
_wglUniform3f(u_transformParam_1_2_5_f, transformParam1, transformParam2, transformParam5);
stateTransformParam1 = transformParam1;
stateTransformParam2 = transformParam2;
stateTransformParam3 = transformParam3;
stateTransformParam4 = transformParam4;
stateTransformParam5 = transformParam5;
}
if (transformParam5 != stateTransformParam5) {
_wglUniform1f(u_transformParam_5_f, transformParam5);
stateTransformParam5 = transformParam5;
if (transformParam3 != stateTransformParam3 || transformParam4 != stateTransformParam4) {
_wglUniform2f(u_transformParam_3_4_f, transformParam3, transformParam4);
stateTransformParam3 = transformParam3;
stateTransformParam4 = transformParam4;
}
int serial = GlStateManager.stateColorSerial;
@ -319,4 +319,8 @@ public class InstancedParticleRenderer {
_wglDrawArraysInstanced(GL_TRIANGLES, 0, 6, particleCount);
}
public static void stupidColorSetHack(IUniformGL color4f) {
_wglUniform4f(color4f, GlStateManager.stateColorR, GlStateManager.stateColorG, GlStateManager.stateColorB, GlStateManager.stateColorA);
}
}

View File

@ -107,7 +107,7 @@ public class DeferredStateManager {
}
public static final boolean isInDeferredPass() {
return GlStateManager.isExtensionPipeline();
return EaglerDeferredPipeline.instance != null && GlStateManager.isExtensionPipeline();
}
public static final boolean isInForwardPass() {
@ -153,10 +153,17 @@ public class DeferredStateManager {
}
public static final void reportForwardRenderObjectPosition2(float x, float y, float z) {
float posX = (float)((x + TileEntityRendererDispatcher.staticPlayerX) - (MathHelper.floor_double(TileEntityRendererDispatcher.staticPlayerX / 16.0) << 4));
float posY = (float)((y + TileEntityRendererDispatcher.staticPlayerY) - (MathHelper.floor_double(TileEntityRendererDispatcher.staticPlayerY / 16.0) << 4));
float posZ = (float)((z + TileEntityRendererDispatcher.staticPlayerZ) - (MathHelper.floor_double(TileEntityRendererDispatcher.staticPlayerZ / 16.0) << 4));
reportForwardRenderObjectPosition((int)posX, (int)posY, (int)posZ);
EaglerDeferredPipeline instance = EaglerDeferredPipeline.instance;
if(instance != null && enableForwardRender) {
EaglerDeferredConfig cfg = instance.config;
if(!cfg.is_rendering_dynamicLights || !cfg.shaderPackInfo.DYNAMIC_LIGHTS) {
return;
}
float posX = (float)((x + TileEntityRendererDispatcher.staticPlayerX) - (MathHelper.floor_double(TileEntityRendererDispatcher.staticPlayerX / 16.0) << 4));
float posY = (float)((y + TileEntityRendererDispatcher.staticPlayerY) - (MathHelper.floor_double(TileEntityRendererDispatcher.staticPlayerY / 16.0) << 4));
float posZ = (float)((z + TileEntityRendererDispatcher.staticPlayerZ) - (MathHelper.floor_double(TileEntityRendererDispatcher.staticPlayerZ / 16.0) << 4));
instance.loadLightSourceBucket((int)posX, (int)posY, (int)posZ);
}
}
public static final void setHDRTranslucentPassBlendFunc() {

View File

@ -2049,6 +2049,8 @@ public class EaglerDeferredPipeline {
}
}
truncateOverflowingLightBuffers();
DeferredStateManager.checkGLError("combineGBuffersAndIlluminate(): RENDER DYNAMIC LIGHTS");
}
@ -2305,6 +2307,19 @@ public class EaglerDeferredPipeline {
return radius2 >= 0.0f;
}
private void truncateOverflowingLightBuffers() {
for(int i = 0; i < this.lightSourceBuckets.length; ++i) {
List<DynamicLightInstance> lst = this.lightSourceBuckets[i];
int k = lst.size();
if(k > MAX_LIGHTS_PER_CHUNK) {
lst.sort(comparatorLightRadius);
for(int l = MAX_LIGHTS_PER_CHUNK - 1; l >= MAX_LIGHTS_PER_CHUNK; --l) {
lst.remove(l);
}
}
}
}
public void updateLightSourceUBO() {
if(currentLightSourceBucket == null) {
currentBoundLightSourceBucket = null;
@ -2332,7 +2347,6 @@ public class EaglerDeferredPipeline {
}
}
private static final List<DynamicLightInstance> tmpListLights = new ArrayList(32);
private static final Comparator<DynamicLightInstance> comparatorLightRadius = (l1, l2) -> {
return l1.radius < l2.radius ? 1 : -1;
};
@ -2340,10 +2354,6 @@ public class EaglerDeferredPipeline {
private void populateLightSourceUBOFromBucket(List<DynamicLightInstance> lights) {
int max = lights.size();
if(max > MAX_LIGHTS_PER_CHUNK) {
tmpListLights.clear();
tmpListLights.addAll(lights);
lights = tmpListLights;
lights.sort(comparatorLightRadius);
max = MAX_LIGHTS_PER_CHUNK;
}
chunkLightingDataCopyBuffer.clear();

View File

@ -124,8 +124,13 @@ public class ForwardAcceleratedEffectRenderer extends AbstractAcceleratedEffectR
shaderProgram.useProgram();
_wglUniform3f(shaderProgram.uniforms.u_texCoordSize2f_particleSize1f, texCoordWidth, texCoordHeight, 0.0625f);
_wglUniform4f(shaderProgram.uniforms.u_transformParam_1_2_3_4_f, f1, f5, f2, f3);
_wglUniform1f(shaderProgram.uniforms.u_transformParam_5_f, f4);
if(shaderProgram.uniforms.u_transformParam_1_2_5_f != null) {
_wglUniform3f(shaderProgram.uniforms.u_transformParam_1_2_5_f, f1, f5, f4);
_wglUniform2f(shaderProgram.uniforms.u_transformParam_3_4_f, f2, f3);
}else {
_wglUniform4f(shaderProgram.uniforms.u_transformParam_1_2_3_4_f, f1, f5, f2, f3);
_wglUniform1f(shaderProgram.uniforms.u_transformParam_5_f, f4);
}
if(isMaterialNormalTexture) {
_wglUniform2f(shaderProgram.uniforms.u_textureYScale2f, 0.5f, 0.5f);
}else {

View File

@ -124,8 +124,13 @@ public class GBufferAcceleratedEffectRenderer extends AbstractAcceleratedEffectR
shaderProgram.useProgram();
_wglUniform3f(shaderProgram.uniforms.u_texCoordSize2f_particleSize1f, texCoordWidth, texCoordHeight, 0.0625f);
_wglUniform4f(shaderProgram.uniforms.u_transformParam_1_2_3_4_f, f1, f5, f2, f3);
_wglUniform1f(shaderProgram.uniforms.u_transformParam_5_f, f4);
if(shaderProgram.uniforms.u_transformParam_1_2_5_f != null) {
_wglUniform3f(shaderProgram.uniforms.u_transformParam_1_2_5_f, f1, f5, f4);
_wglUniform2f(shaderProgram.uniforms.u_transformParam_3_4_f, f2, f3);
}else {
_wglUniform4f(shaderProgram.uniforms.u_transformParam_1_2_3_4_f, f1, f5, f2, f3);
_wglUniform1f(shaderProgram.uniforms.u_transformParam_5_f, f4);
}
if(isMaterialNormalTexture) {
_wglUniform2f(shaderProgram.uniforms.u_textureYScale2f, 0.5f, 0.5f);
}else {

View File

@ -69,6 +69,8 @@ public class PipelineShaderAccelParticleForward extends ShaderProgram<PipelineSh
public IUniformGL u_texCoordSize2f_particleSize1f = null;
public IUniformGL u_transformParam_1_2_3_4_f = null;
public IUniformGL u_transformParam_5_f = null;
public IUniformGL u_transformParam_1_2_5_f = null;
public IUniformGL u_transformParam_3_4_f = null;
public IUniformGL u_textureYScale2f = null;
public int u_chunkLightingDataBlockBinding = -1;
@ -85,6 +87,8 @@ public class PipelineShaderAccelParticleForward extends ShaderProgram<PipelineSh
u_texCoordSize2f_particleSize1f = _wglGetUniformLocation(prog, "u_texCoordSize2f_particleSize1f");
u_transformParam_1_2_3_4_f = _wglGetUniformLocation(prog, "u_transformParam_1_2_3_4_f");
u_transformParam_5_f = _wglGetUniformLocation(prog, "u_transformParam_5_f");
u_transformParam_1_2_5_f = _wglGetUniformLocation(prog, "u_transformParam_1_2_5_f");
u_transformParam_3_4_f = _wglGetUniformLocation(prog, "u_transformParam_3_4_f");
u_textureYScale2f = _wglGetUniformLocation(prog, "u_textureYScale2f");
_wglUniform1i(_wglGetUniformLocation(prog, "u_diffuseTexture"), 0);
_wglUniform1i(_wglGetUniformLocation(prog, "u_samplerNormalMaterial"), 2);

View File

@ -53,6 +53,8 @@ public class PipelineShaderAccelParticleGBuffer extends ShaderProgram<PipelineSh
public IUniformGL u_texCoordSize2f_particleSize1f = null;
public IUniformGL u_transformParam_1_2_3_4_f = null;
public IUniformGL u_transformParam_5_f = null;
public IUniformGL u_transformParam_1_2_5_f = null;
public IUniformGL u_transformParam_3_4_f = null;
public IUniformGL u_textureYScale2f = null;
private Uniforms() {
@ -64,6 +66,8 @@ public class PipelineShaderAccelParticleGBuffer extends ShaderProgram<PipelineSh
u_texCoordSize2f_particleSize1f = _wglGetUniformLocation(prog, "u_texCoordSize2f_particleSize1f");
u_transformParam_1_2_3_4_f = _wglGetUniformLocation(prog, "u_transformParam_1_2_3_4_f");
u_transformParam_5_f = _wglGetUniformLocation(prog, "u_transformParam_5_f");
u_transformParam_1_2_5_f = _wglGetUniformLocation(prog, "u_transformParam_1_2_5_f");
u_transformParam_3_4_f = _wglGetUniformLocation(prog, "u_transformParam_3_4_f");
u_textureYScale2f = _wglGetUniformLocation(prog, "u_textureYScale2f");
_wglUniform1i(_wglGetUniformLocation(prog, "u_diffuseTexture"), 0);
_wglUniform1i(_wglGetUniformLocation(prog, "u_samplerNormalMaterial"), 2);

View File

@ -92,6 +92,11 @@ public class ShaderSource {
public static final ResourceLocation post_fxaa_fsh = new ResourceLocation("eagler:glsl/deferred/post_fxaa.fsh");
public static final ResourceLocation hand_depth_mask_fsh = new ResourceLocation("eagler:glsl/deferred/hand_depth_mask.fsh");
public static final ResourceLocation core_dynamiclights_vsh = new ResourceLocation("eagler:glsl/dynamiclights/core_dynamiclights.vsh");
public static final ResourceLocation core_dynamiclights_fsh = new ResourceLocation("eagler:glsl/dynamiclights/core_dynamiclights.fsh");
public static final ResourceLocation accel_particle_dynamiclights_vsh = new ResourceLocation("eagler:glsl/dynamiclights/accel_particle_dynamiclights.vsh");
public static final ResourceLocation accel_particle_dynamiclights_fsh = new ResourceLocation("eagler:glsl/dynamiclights/accel_particle_dynamiclights.fsh");
private static final Map<ResourceLocation, String> sourceCache = new HashMap();
private static boolean isHighP = false;

View File

@ -0,0 +1,287 @@
package net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights;
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import static net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.ExtGLEnums.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.IBufferGL;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
import net.lax1dude.eaglercraft.v1_8.opengl.EaglercraftGPU;
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.ArrayListSerial;
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.EaglerDeferredPipeline;
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.ListSerial;
import net.minecraft.util.MathHelper;
/**
* Copyright (c) 2023-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class DynamicLightBucketLoader {
public IBufferGL buffer_chunkLightingData;
private ByteBuffer chunkLightingDataCopyBuffer;
private boolean isChunkLightingEnabled = false;
public ListSerial<DynamicLightInstance> currentBoundLightSourceBucket;
public final ListSerial<DynamicLightInstance>[] lightSourceBuckets;
public ListSerial<DynamicLightInstance> currentLightSourceBucket;
public static final int MAX_LIGHTS_PER_CHUNK = 12;
private final int lightSourceBucketsWidth;
private final int lightSourceBucketsHeight;
private double currentRenderX = 0.0;
private double currentRenderY = 0.0;
private double currentRenderZ = 0.0;
public DynamicLightBucketLoader() {
this.lightSourceBucketsWidth = 5;
this.lightSourceBucketsHeight = 3;
int cnt = 5 * 3 * 5;
this.lightSourceBuckets = new ListSerial[cnt];
}
public void initialize() {
destroy();
buffer_chunkLightingData = _wglGenBuffers();
EaglercraftGPU.bindGLUniformBuffer(buffer_chunkLightingData);
int lightingDataLength = 4 * MAX_LIGHTS_PER_CHUNK + 4;
chunkLightingDataCopyBuffer = EagRuntime.allocateByteBuffer(lightingDataLength << 2);
for(int i = 0; i < lightingDataLength; ++i) {
chunkLightingDataCopyBuffer.putInt(0);
}
chunkLightingDataCopyBuffer.flip();
_wglBufferData(_GL_UNIFORM_BUFFER, chunkLightingDataCopyBuffer, GL_DYNAMIC_DRAW);
for(int i = 0; i < this.lightSourceBuckets.length; ++i) {
this.lightSourceBuckets[i] = new ArrayListSerial(16);
}
}
public void clearBuckets() {
for(int i = 0; i < this.lightSourceBuckets.length; ++i) {
this.lightSourceBuckets[i].clear();
}
}
public void loadLightSourceBucket(int relativeBlockX, int relativeBlockY, int relativeBlockZ) {
int hw = lightSourceBucketsWidth / 2;
int hh = lightSourceBucketsHeight / 2;
int bucketX = (relativeBlockX >> 4) + hw;
int bucketY = (relativeBlockY >> 4) + hh;
int bucketZ = (relativeBlockZ >> 4) + hw;
if(bucketX >= 0 && bucketY >= 0 && bucketZ >= 0 && bucketX < lightSourceBucketsWidth
&& bucketY < lightSourceBucketsHeight && bucketZ < lightSourceBucketsWidth) {
currentLightSourceBucket = lightSourceBuckets[bucketY * lightSourceBucketsWidth * lightSourceBucketsWidth
+ bucketZ * lightSourceBucketsWidth + bucketX];
}else {
currentLightSourceBucket = null;
}
updateLightSourceUBO();
}
public ListSerial<DynamicLightInstance> getLightSourceBucketRelativeChunkCoords(int cx, int cy, int cz) {
int hw = lightSourceBucketsWidth / 2;
int hh = lightSourceBucketsHeight / 2;
cx += hw;
cy += hh;
cz += hw;
if(cx < 0 || cx >= lightSourceBucketsWidth || cy < 0 || cy >= lightSourceBucketsHeight || cz < 0
|| cz >= lightSourceBucketsWidth) {
return null;
}else {
return lightSourceBuckets[cy * lightSourceBucketsWidth * lightSourceBucketsWidth
+ cz * lightSourceBucketsWidth + cx];
}
}
public void addLightSourceToBucket(int cx, int cy, int cz, DynamicLightInstance dl) {
ListSerial<DynamicLightInstance> lst = getLightSourceBucketRelativeChunkCoords(cx, cy, cz);
if(lst != null) {
lst.add(dl);
}
}
public void bucketLightSource(float x, float y, float z, DynamicLightInstance dl) {
int bucketX = MathHelper.floor_float(x / 16.0f);
int bucketY = MathHelper.floor_float(y / 16.0f);
int bucketZ = MathHelper.floor_float(z / 16.0f);
addLightSourceToBucket(bucketX, bucketY, bucketZ, dl);
int minX = bucketX, maxX = bucketX;
int minY = bucketY, maxY = bucketY;
int minZ = bucketZ, maxZ = bucketZ;
float lightLocalX = x - (bucketX << 4);
float lightLocalY = y - (bucketY << 4);
float lightLocalZ = z - (bucketZ << 4);
float radius = dl.radius;
boolean outOfBounds = false;
if(lightLocalX - radius < 0.0f) {
minX -= 1;
outOfBounds = true;
addLightSourceToBucket(bucketX - 1, bucketY, bucketZ, dl);
}
if(lightLocalY - radius < 0.0f) {
minY -= 1;
outOfBounds = true;
addLightSourceToBucket(bucketX, bucketY - 1, bucketZ, dl);
}
if(lightLocalZ - radius < 0.0f) {
minZ -= 1;
outOfBounds = true;
addLightSourceToBucket(bucketX, bucketY, bucketZ - 1, dl);
}
if(lightLocalX + radius >= 16.0f) {
maxX += 1;
outOfBounds = true;
addLightSourceToBucket(bucketX + 1, bucketY, bucketZ, dl);
}
if(lightLocalY + radius >= 16.0f) {
maxY += 1;
outOfBounds = true;
addLightSourceToBucket(bucketX, bucketY + 1, bucketZ, dl);
}
if(lightLocalZ + radius >= 16.0f) {
maxZ += 1;
outOfBounds = true;
addLightSourceToBucket(bucketX, bucketY, bucketZ + 1, dl);
}
if(!outOfBounds) {
return;
}
radius *= radius;
for(int yy = minY; yy <= maxY; ++yy) {
for(int zz = minZ; zz <= maxZ; ++zz) {
for(int xx = minX; xx <= maxX; ++xx) {
if((xx == bucketX ? 1 : 0) + (yy == bucketY ? 1 : 0) + (zz == bucketZ ? 1 : 0) > 1) {
continue;
}
List<DynamicLightInstance> lst = getLightSourceBucketRelativeChunkCoords(xx, yy, zz);
if(lst != null) {
int bucketBoundsX = xx << 4;
int bucketBoundsY = yy << 4;
int bucketBoundsZ = zz << 4;
if (EaglerDeferredPipeline.testAabSphere(bucketBoundsX, bucketBoundsY, bucketBoundsZ,
bucketBoundsX + 16, bucketBoundsY + 16, bucketBoundsZ + 16, x, y, z, radius)) {
lst.add(dl);
}
}
}
}
}
}
public void truncateOverflowingBuffers() {
for(int i = 0; i < this.lightSourceBuckets.length; ++i) {
List<DynamicLightInstance> lst = this.lightSourceBuckets[i];
int k = lst.size();
if(k > MAX_LIGHTS_PER_CHUNK) {
lst.sort(comparatorLightRadius);
for(int l = MAX_LIGHTS_PER_CHUNK - 1; l >= MAX_LIGHTS_PER_CHUNK; --l) {
lst.remove(l);
}
}
}
}
public void updateLightSourceUBO() {
if(currentLightSourceBucket == null) {
currentBoundLightSourceBucket = null;
if(isChunkLightingEnabled) {
isChunkLightingEnabled = false;
EaglercraftGPU.bindGLUniformBuffer(buffer_chunkLightingData);
chunkLightingDataCopyBuffer.clear();
chunkLightingDataCopyBuffer.putInt(0);
chunkLightingDataCopyBuffer.flip();
_wglBufferSubData(_GL_UNIFORM_BUFFER, 0, chunkLightingDataCopyBuffer);
}
}else {
boolean isNew;
if(!isChunkLightingEnabled) {
isChunkLightingEnabled = true;
isNew = true;
}else {
isNew = currentLightSourceBucket != currentBoundLightSourceBucket;
}
currentBoundLightSourceBucket = currentLightSourceBucket;
if(isNew || currentBoundLightSourceBucket.eaglerCheck()) {
populateLightSourceUBOFromBucket(currentBoundLightSourceBucket);
currentBoundLightSourceBucket.eaglerResetCheck();
}
}
}
private static final Comparator<DynamicLightInstance> comparatorLightRadius = (l1, l2) -> {
return l1.radius < l2.radius ? 1 : -1;
};
private void populateLightSourceUBOFromBucket(List<DynamicLightInstance> lights) {
int max = lights.size();
if(max > MAX_LIGHTS_PER_CHUNK) {
//tmpListLights.clear();
//tmpListLights.addAll(lights);
//lights = tmpListLights;
//lights.sort(comparatorLightRadius);
max = MAX_LIGHTS_PER_CHUNK;
}
chunkLightingDataCopyBuffer.clear();
chunkLightingDataCopyBuffer.putInt(max);
if(max > 0) {
chunkLightingDataCopyBuffer.putInt(0); //padding
chunkLightingDataCopyBuffer.putInt(0); //padding
chunkLightingDataCopyBuffer.putInt(0); //padding
for(int i = 0; i < max; ++i) {
DynamicLightInstance dl = lights.get(i);
chunkLightingDataCopyBuffer.putFloat((float)(dl.posX - currentRenderX));
chunkLightingDataCopyBuffer.putFloat((float)(dl.posY - currentRenderY));
chunkLightingDataCopyBuffer.putFloat((float)(dl.posZ - currentRenderZ));
chunkLightingDataCopyBuffer.putFloat(dl.radius);
}
}
chunkLightingDataCopyBuffer.flip();
EaglercraftGPU.bindGLUniformBuffer(buffer_chunkLightingData);
_wglBufferSubData(_GL_UNIFORM_BUFFER, 0, chunkLightingDataCopyBuffer);
}
public void setRenderPos(double currentRenderX, double currentRenderY, double currentRenderZ) {
this.currentRenderX = currentRenderX;
this.currentRenderY = currentRenderY;
this.currentRenderZ = currentRenderZ;
}
public void bindUniformBuffer(int index) {
EaglercraftGPU.bindGLUniformBuffer(buffer_chunkLightingData);
EaglercraftGPU.bindUniformBufferRange(index, buffer_chunkLightingData, 0, chunkLightingDataCopyBuffer.capacity());
}
public void destroy() {
if(chunkLightingDataCopyBuffer != null) {
EagRuntime.freeByteBuffer(chunkLightingDataCopyBuffer);
chunkLightingDataCopyBuffer = null;
}
if(buffer_chunkLightingData != null) {
_wglDeleteBuffers(buffer_chunkLightingData);
buffer_chunkLightingData = null;
}
for(int i = 0; i < this.lightSourceBuckets.length; ++i) {
this.lightSourceBuckets[i] = null;
}
}
}

View File

@ -0,0 +1,48 @@
package net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
class DynamicLightInstance {
public final String lightName;
long lastCacheHit = 0l;
double posX;
double posY;
double posZ;
float radius;
public DynamicLightInstance(String lightName) {
this.lightName = lightName;
}
public void updateLight(double posX, double posY, double posZ, float radius) {
this.lastCacheHit = System.currentTimeMillis();
this.posX = posX;
this.posY = posY;
this.posZ = posZ;
this.radius = radius;
}
public void destroy() {
}
public float getRadiusInWorld() {
return radius;
}
}

View File

@ -0,0 +1,230 @@
package net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights;
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.IBufferArrayGL;
import net.lax1dude.eaglercraft.v1_8.internal.IBufferGL;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.FloatBuffer;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.lax1dude.eaglercraft.v1_8.opengl.EaglercraftGPU;
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
import net.lax1dude.eaglercraft.v1_8.opengl.InstancedParticleRenderer;
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.AbstractAcceleratedEffectRenderer;
import net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights.program.DynamicLightsAccelParticleShader;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.entity.Entity;
import net.minecraft.util.MathHelper;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class DynamicLightsAcceleratedEffectRenderer extends AbstractAcceleratedEffectRenderer {
private static final Logger logger = LogManager.getLogger("DynamicLightsAcceleratedEffectRenderer");
private ByteBuffer particleBuffer = null;
private int particleCount = 0;
private boolean particlesHasOverflowed = false;
private static final int BYTES_PER_PARTICLE = 24;
private static final int PARTICLE_LIMIT = 5461;
private DynamicLightsAccelParticleShader shaderProgram = null;
private IBufferArrayGL vertexArray = null;
private IBufferGL vertexBuffer = null;
private IBufferGL instancesBuffer = null;
private float f1;
private float f2;
private float f3;
private float f4;
private float f5;
public static boolean isMaterialNormalTexture = false;
public void initialize() {
destroy();
if(DynamicLightsPipelineCompiler.matrixCopyBuffer == null) {
DynamicLightsPipelineCompiler.matrixCopyBuffer = GLAllocation.createDirectFloatBuffer(16);
}
shaderProgram = DynamicLightsAccelParticleShader.compile();
shaderProgram.loadUniforms();
particleBuffer = EagRuntime.allocateByteBuffer(PARTICLE_LIMIT * BYTES_PER_PARTICLE);
vertexArray = _wglGenVertexArrays();
vertexBuffer = _wglGenBuffers();
instancesBuffer = _wglGenBuffers();
FloatBuffer verts = EagRuntime.allocateFloatBuffer(12);
verts.put(new float[] {
-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f
});
verts.flip();
EaglercraftGPU.bindGLBufferArray(vertexArray);
EaglercraftGPU.bindGLArrayBuffer(vertexBuffer);
_wglBufferData(GL_ARRAY_BUFFER, verts, GL_STATIC_DRAW);
EagRuntime.freeFloatBuffer(verts);
_wglEnableVertexAttribArray(0);
_wglVertexAttribPointer(0, 2, GL_FLOAT, false, 8, 0);
_wglVertexAttribDivisor(0, 0);
EaglercraftGPU.bindGLArrayBuffer(instancesBuffer);
_wglBufferData(GL_ARRAY_BUFFER, particleBuffer.remaining(), GL_STREAM_DRAW);
_wglEnableVertexAttribArray(1);
_wglVertexAttribPointer(1, 3, GL_FLOAT, false, 24, 0);
_wglVertexAttribDivisor(1, 1);
_wglEnableVertexAttribArray(2);
_wglVertexAttribPointer(2, 2, GL_UNSIGNED_SHORT, false, 24, 12);
_wglVertexAttribDivisor(2, 1);
_wglEnableVertexAttribArray(3);
_wglVertexAttribPointer(3, 2, GL_UNSIGNED_BYTE, true, 24, 16);
_wglVertexAttribDivisor(3, 1);
_wglEnableVertexAttribArray(4);
_wglVertexAttribPointer(4, 2, GL_UNSIGNED_BYTE, false, 24, 18);
_wglVertexAttribDivisor(4, 1);
_wglEnableVertexAttribArray(5);
_wglVertexAttribPointer(5, 4, GL_UNSIGNED_BYTE, true, 24, 20);
_wglVertexAttribDivisor(5, 1);
}
@Override
public void draw(float texCoordWidth, float texCoordHeight) {
if(particleCount == 0) {
return;
}
shaderProgram.useProgram();
_wglUniform3f(shaderProgram.uniforms.u_texCoordSize2f_particleSize1f, texCoordWidth, texCoordHeight, 0.0625f);
_wglUniform3f(shaderProgram.uniforms.u_transformParam_1_2_5_f, f1, f5, f4);
_wglUniform2f(shaderProgram.uniforms.u_transformParam_3_4_f, f2, f3);
InstancedParticleRenderer.stupidColorSetHack(shaderProgram.uniforms.u_color4f);
FloatBuffer buf = DynamicLightsPipelineCompiler.matrixCopyBuffer;
buf.clear();
GlStateManager.getFloat(GL_MODELVIEW_MATRIX, buf);
buf.flip();
_wglUniformMatrix4fv(shaderProgram.uniforms.u_modelViewMatrix4f, false, buf);
buf.clear();
GlStateManager.getFloat(GL_PROJECTION_MATRIX, buf);
buf.flip();
_wglUniformMatrix4fv(shaderProgram.uniforms.u_projectionMatrix4f, false, buf);
buf.clear();
DynamicLightsStateManager.inverseViewMatrix.store(buf);
buf.flip();
_wglUniformMatrix4fv(shaderProgram.uniforms.u_inverseViewMatrix4f, false, buf);
EaglercraftGPU.bindGLArrayBuffer(instancesBuffer);
EaglercraftGPU.bindGLBufferArray(vertexArray);
int p = particleBuffer.position();
int l = particleBuffer.limit();
particleBuffer.flip();
_wglBufferSubData(GL_ARRAY_BUFFER, 0, particleBuffer);
particleBuffer.position(p);
particleBuffer.limit(l);
_wglDrawArraysInstanced(GL_TRIANGLES, 0, 6, particleCount);
}
@Override
public void begin(float partialTicks) {
this.partialTicks = partialTicks;
particleBuffer.clear();
particleCount = 0;
particlesHasOverflowed = false;
Entity et = Minecraft.getMinecraft().getRenderViewEntity();
if(et != null) {
f1 = MathHelper.cos(et.rotationYaw * 0.017453292F);
f2 = MathHelper.sin(et.rotationYaw * 0.017453292F);
f3 = -f2 * MathHelper.sin(et.rotationPitch * 0.017453292F);
f4 = f1 * MathHelper.sin(et.rotationPitch * 0.017453292F);
f5 = MathHelper.cos(et.rotationPitch * 0.017453292F);
}
}
@Override
public void drawParticle(float posX, float posY, float posZ, int particleIndexX, int particleIndexY,
int lightMapData, int texSize, float particleSize, int rgba) {
if(particlesHasOverflowed) {
return;
}
if(particleCount >= PARTICLE_LIMIT) {
particlesHasOverflowed = true;
logger.error("Particle buffer has overflowed! Exceeded {} particles, no more particles will be rendered.", PARTICLE_LIMIT);
return;
}
++particleCount;
ByteBuffer buf = particleBuffer;
buf.putFloat(posX);
buf.putFloat(posY);
buf.putFloat(posZ);
buf.putShort((short)particleIndexX);
buf.putShort((short)particleIndexY);
buf.put((byte)(lightMapData & 0xFF));
buf.put((byte)((lightMapData >> 16) & 0xFF));
buf.put((byte)(particleSize * 16.0f));
buf.put((byte)texSize);
buf.putInt(rgba);
}
public void destroy() {
if(particleBuffer != null) {
EagRuntime.freeByteBuffer(particleBuffer);
particleBuffer = null;
}
if(shaderProgram != null) {
shaderProgram.destroy();
shaderProgram = null;
}
if(vertexArray != null) {
_wglDeleteVertexArrays(vertexArray);
vertexArray = null;
}
if(vertexBuffer != null) {
_wglDeleteBuffers(vertexBuffer);
vertexBuffer = null;
}
if(instancesBuffer != null) {
_wglDeleteBuffers(instancesBuffer);
instancesBuffer = null;
}
}
}

View File

@ -0,0 +1,105 @@
package net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights;
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
import net.lax1dude.eaglercraft.v1_8.internal.IProgramGL;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.FloatBuffer;
import net.lax1dude.eaglercraft.v1_8.opengl.FixedFunctionShader.FixedFunctionState;
import net.lax1dude.eaglercraft.v1_8.opengl.IExtPipelineCompiler;
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.program.ShaderSource;
import net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights.program.DynamicLightsExtPipelineShader;
import net.lax1dude.eaglercraft.v1_8.vector.Matrix4f;
import net.minecraft.client.renderer.GLAllocation;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class DynamicLightsPipelineCompiler implements IExtPipelineCompiler {
static FloatBuffer matrixCopyBuffer = null;
private static class PipelineInstance {
private final int coreBits;
private final int extBits;
private DynamicLightsExtPipelineShader shader;
public PipelineInstance(int coreBits, int extBits) {
this.coreBits = coreBits;
this.extBits = extBits;
}
}
@Override
public String[] getShaderSource(int stateCoreBits, int stateExtBits, Object[] userPointer) {
if(matrixCopyBuffer == null) {
matrixCopyBuffer = GLAllocation.createDirectFloatBuffer(16);
}
userPointer[0] = new PipelineInstance(stateCoreBits, stateExtBits);
return new String[] {
ShaderSource.getSourceFor(ShaderSource.core_dynamiclights_vsh),
ShaderSource.getSourceFor(ShaderSource.core_dynamiclights_fsh)
};
}
@Override
public int getExtensionStatesCount() {
return 0;
}
@Override
public int getCurrentExtensionStateBits(int stateCoreBits) {
return 0;
}
@Override
public int getCoreStateMask(int stateExtBits) {
return 0xFFFFFFFF;
}
@Override
public void initializeNewShader(IProgramGL compiledProg, int stateCoreBits, int stateExtBits,
Object[] userPointer) {
DynamicLightsExtPipelineShader newShader = new DynamicLightsExtPipelineShader(compiledProg, stateCoreBits);
((PipelineInstance)userPointer[0]).shader = newShader;
newShader.loadUniforms();
}
@Override
public void updatePipeline(IProgramGL compiledProg, int stateCoreBits, int stateExtBits, Object[] userPointer) {
if((stateCoreBits & FixedFunctionState.STATE_ENABLE_LIGHTMAP) != 0) {
DynamicLightsExtPipelineShader.Uniforms uniforms = ((PipelineInstance)userPointer[0]).shader.uniforms;
if(uniforms.u_inverseViewMatrix4f != null) {
int serial = DynamicLightsStateManager.inverseViewMatrixSerial;
if(uniforms.inverseViewMatrixSerial != serial) {
uniforms.inverseViewMatrixSerial = serial;
FloatBuffer buf = matrixCopyBuffer;
buf.clear();
DynamicLightsStateManager.inverseViewMatrix.store(buf);
buf.flip();
_wglUniformMatrix4fv(uniforms.u_inverseViewMatrix4f, false, buf);
}
}
}
}
@Override
public void destroyPipeline(IProgramGL shaderProgram, int stateCoreBits, int stateExtBits, Object[] userPointer) {
}
}

View File

@ -0,0 +1,169 @@
package net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import net.lax1dude.eaglercraft.v1_8.opengl.FixedFunctionPipeline;
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
import net.lax1dude.eaglercraft.v1_8.vector.Matrix4f;
import net.minecraft.client.particle.EffectRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.util.MathHelper;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class DynamicLightsStateManager {
static final DynamicLightsPipelineCompiler deferredExtPipeline = new DynamicLightsPipelineCompiler();
static final Map<String, DynamicLightInstance> lightRenderers = new HashMap();
static final List<DynamicLightInstance> lightRenderList = new LinkedList();
static final Matrix4f inverseViewMatrix = new Matrix4f();
static int inverseViewMatrixSerial = 0;
static DynamicLightBucketLoader bucketLoader = null;
static DynamicLightsAcceleratedEffectRenderer accelParticleRenderer = null;
static int lastTotal = 0;
static long renderTimeout = 5000l;
private static long lastTick = 0l;
public static final void enableDynamicLightsRender() {
if(bucketLoader == null) {
bucketLoader = new DynamicLightBucketLoader();
bucketLoader.initialize();
bucketLoader.bindUniformBuffer(0);
FixedFunctionPipeline.loadExtensionPipeline(deferredExtPipeline);
}
if(accelParticleRenderer == null) {
accelParticleRenderer = new DynamicLightsAcceleratedEffectRenderer();
accelParticleRenderer.initialize();
}
}
public static final void bindAcceleratedEffectRenderer(EffectRenderer renderer) {
renderer.acceleratedParticleRenderer = accelParticleRenderer;
}
public static final void disableDynamicLightsRender(boolean unloadPipeline) {
if(bucketLoader != null) {
bucketLoader.destroy();
bucketLoader = null;
if(unloadPipeline) {
FixedFunctionPipeline.loadExtensionPipeline(null);
}
}
if(accelParticleRenderer != null) {
accelParticleRenderer.destroy();
accelParticleRenderer = null;
}
destroyAll();
lightRenderList.clear();
}
public static final boolean isDynamicLightsRender() {
return bucketLoader != null;
}
public static final boolean isInDynamicLightsPass() {
return GlStateManager.isExtensionPipeline() && bucketLoader != null;
}
public static final void reportForwardRenderObjectPosition(int centerX, int centerY, int centerZ) {
if(bucketLoader != null) {
bucketLoader.loadLightSourceBucket(centerX, centerY, centerZ);
}
}
public static final void reportForwardRenderObjectPosition2(float x, float y, float z) {
if(bucketLoader != null) {
float posX = (float)((x + TileEntityRendererDispatcher.staticPlayerX) - (MathHelper.floor_double(TileEntityRendererDispatcher.staticPlayerX / 16.0) << 4));
float posY = (float)((y + TileEntityRendererDispatcher.staticPlayerY) - (MathHelper.floor_double(TileEntityRendererDispatcher.staticPlayerY / 16.0) << 4));
float posZ = (float)((z + TileEntityRendererDispatcher.staticPlayerZ) - (MathHelper.floor_double(TileEntityRendererDispatcher.staticPlayerZ / 16.0) << 4));
bucketLoader.loadLightSourceBucket((int)posX, (int)posY, (int)posZ);
}
}
public static final void renderDynamicLight(String lightName, double posX, double posY, double posZ, float radius) {
if(bucketLoader != null) {
DynamicLightInstance dl = lightRenderers.get(lightName);
if(dl == null) {
lightRenderers.put(lightName, dl = new DynamicLightInstance(lightName));
}
dl.updateLight(posX, posY, posZ, radius);
lightRenderList.add(dl);
}
}
public static final void clearRenderList() {
lightRenderList.clear();
}
public static final void commitLightSourceBuckets(double renderPosX, double renderPosY, double renderPosZ) {
updateTimers();
lastTotal = lightRenderList.size();
if(bucketLoader != null) {
bucketLoader.clearBuckets();
int entityChunkOriginX = MathHelper.floor_double(renderPosX / 16.0) << 4;
int entityChunkOriginY = MathHelper.floor_double(renderPosY / 16.0) << 4;
int entityChunkOriginZ = MathHelper.floor_double(renderPosZ / 16.0) << 4;
Iterator<DynamicLightInstance> itr = lightRenderList.iterator();
while(itr.hasNext()) {
DynamicLightInstance dl = itr.next();
float lightChunkPosX = (float)(dl.posX - entityChunkOriginX);
float lightChunkPosY = (float)(dl.posY - entityChunkOriginY);
float lightChunkPosZ = (float)(dl.posZ - entityChunkOriginZ);
bucketLoader.bucketLightSource(lightChunkPosX, lightChunkPosY, lightChunkPosZ, dl);
}
bucketLoader.setRenderPos(renderPosX, renderPosY, renderPosZ);
bucketLoader.truncateOverflowingBuffers();
}
lightRenderList.clear();
}
public static final void setupInverseViewMatrix() {
Matrix4f.invert(GlStateManager.getModelViewReference(), inverseViewMatrix);
inverseViewMatrixSerial = GlStateManager.getModelViewSerial();
}
private static final void updateTimers() {
long millis = System.currentTimeMillis();
if(millis - lastTick > 1000l) {
lastTick = millis;
Iterator<DynamicLightInstance> itr = lightRenderers.values().iterator();
while(itr.hasNext()) {
DynamicLightInstance dl = itr.next();
if(millis - dl.lastCacheHit > renderTimeout) {
dl.destroy();
itr.remove();
}
}
}
}
public static final void destroyAll() {
Iterator<DynamicLightInstance> itr = lightRenderers.values().iterator();
while(itr.hasNext()) {
itr.next().destroy();
}
lightRenderers.clear();
}
public static String getF3String() {
return "DynamicLightsTotal: " + lastTotal;
}
}

View File

@ -0,0 +1,95 @@
package net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights.program;
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.GL_FRAGMENT_SHADER;
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.GL_VERTEX_SHADER;
import java.util.ArrayList;
import java.util.List;
import net.lax1dude.eaglercraft.v1_8.internal.IProgramGL;
import net.lax1dude.eaglercraft.v1_8.internal.IShaderGL;
import net.lax1dude.eaglercraft.v1_8.internal.IUniformGL;
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.program.IProgramUniforms;
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.program.ShaderCompiler;
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.program.ShaderProgram;
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.program.ShaderSource;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class DynamicLightsAccelParticleShader extends ShaderProgram<DynamicLightsAccelParticleShader.Uniforms> {
public static DynamicLightsAccelParticleShader compile() {
IShaderGL accelParticleVSH = ShaderCompiler.compileShader("accel_particle_dynamiclights", GL_VERTEX_SHADER,
ShaderSource.accel_particle_dynamiclights_vsh);
IShaderGL accelParticleFSH = null;
try {
accelParticleFSH = ShaderCompiler.compileShader("accel_particle_dynamiclights", GL_FRAGMENT_SHADER,
ShaderSource.accel_particle_dynamiclights_fsh);
IProgramGL prog = ShaderCompiler.linkProgram("accel_particle_dynamiclights", accelParticleVSH, accelParticleFSH);
return new DynamicLightsAccelParticleShader(prog);
}finally {
if(accelParticleVSH != null) {
accelParticleVSH.free();
}
if(accelParticleFSH != null) {
accelParticleFSH.free();
}
}
}
private DynamicLightsAccelParticleShader(IProgramGL prog) {
super(prog, new Uniforms());
}
public static class Uniforms implements IProgramUniforms {
public IUniformGL u_color4f = null;
public IUniformGL u_modelViewMatrix4f = null;
public IUniformGL u_projectionMatrix4f = null;
public IUniformGL u_inverseViewMatrix4f = null;
public IUniformGL u_texCoordSize2f_particleSize1f = null;
public IUniformGL u_transformParam_1_2_5_f = null;
public IUniformGL u_transformParam_3_4_f = null;
public int u_chunkLightingDataBlockBinding = -1;
private Uniforms() {
}
@Override
public void loadUniforms(IProgramGL prog) {
u_modelViewMatrix4f = _wglGetUniformLocation(prog, "u_modelViewMatrix4f");
u_projectionMatrix4f = _wglGetUniformLocation(prog, "u_projectionMatrix4f");
u_inverseViewMatrix4f = _wglGetUniformLocation(prog, "u_inverseViewMatrix4f");
u_texCoordSize2f_particleSize1f = _wglGetUniformLocation(prog, "u_texCoordSize2f_particleSize1f");
u_transformParam_1_2_5_f = _wglGetUniformLocation(prog, "u_transformParam_1_2_5_f");
u_transformParam_3_4_f = _wglGetUniformLocation(prog, "u_transformParam_3_4_f");
u_color4f = _wglGetUniformLocation(prog, "u_color4f");
_wglUniform1i(_wglGetUniformLocation(prog, "u_inputTexture"), 0);
_wglUniform1i(_wglGetUniformLocation(prog, "u_lightmapTexture"), 1);
int blockIndex = _wglGetUniformBlockIndex(prog, "u_chunkLightingData");
if(blockIndex != -1) {
_wglUniformBlockBinding(prog, blockIndex, 0);
u_chunkLightingDataBlockBinding = 0;
}else {
u_chunkLightingDataBlockBinding = -1;
}
}
}
}

View File

@ -0,0 +1,58 @@
package net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights.program;
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
import net.lax1dude.eaglercraft.v1_8.internal.IProgramGL;
import net.lax1dude.eaglercraft.v1_8.internal.IUniformGL;
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.program.IProgramUniforms;
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.program.ShaderProgram;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class DynamicLightsExtPipelineShader extends ShaderProgram<DynamicLightsExtPipelineShader.Uniforms> {
public final int coreState;
public DynamicLightsExtPipelineShader(IProgramGL program, int coreState) {
super(program, new Uniforms());
this.coreState = coreState;
}
public static class Uniforms implements IProgramUniforms {
public int u_chunkLightingDataBlockBinding = -1;
public int inverseViewMatrixSerial = -1;
public IUniformGL u_inverseViewMatrix4f = null;
Uniforms() {
}
@Override
public void loadUniforms(IProgramGL prog) {
u_inverseViewMatrix4f = _wglGetUniformLocation(prog, "u_inverseViewMatrix4f");
int blockIndex = _wglGetUniformBlockIndex(prog, "u_chunkLightingData");
if(blockIndex != -1) {
_wglUniformBlockBinding(prog, blockIndex, 0);
u_chunkLightingDataBlockBinding = 0;
}else {
u_chunkLightingDataBlockBinding = -1;
}
}
}
}

View File

@ -70,6 +70,8 @@ public class SingleplayerServerController implements ISaveFormat {
public static final ClientIntegratedServerNetworkManager localPlayerNetworkManager = new ClientIntegratedServerNetworkManager(PLAYER_CHANNEL);
private static final List<String> openLANChannels = new ArrayList();
private static final IPCPacketManager packetManagerInstance = new IPCPacketManager();
private SingleplayerServerController() {
}
@ -247,7 +249,7 @@ public class SingleplayerServerController implements ISaveFormat {
if(packetData.channel.equals(SingleplayerServerController.IPC_CHANNEL)) {
IPCPacketBase ipc;
try {
ipc = IPCPacketManager.IPCDeserialize(packetData.contents);
ipc = packetManagerInstance.IPCDeserialize(packetData.contents);
}catch(IOException ex) {
throw new RuntimeException("Failed to deserialize IPC packet", ex);
}
@ -402,7 +404,7 @@ public class SingleplayerServerController implements ISaveFormat {
public static void sendIPCPacket(IPCPacketBase ipc) {
byte[] pkt;
try {
pkt = IPCPacketManager.IPCSerialize(ipc);
pkt = packetManagerInstance.IPCSerialize(ipc);
}catch (IOException ex) {
throw new RuntimeException("Failed to serialize IPC packet", ex);
}

View File

@ -11,6 +11,7 @@ import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiYesNo;
import net.minecraft.client.resources.I18n;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.world.storage.WorldInfo;
/**
@ -38,6 +39,7 @@ public class GuiScreenBackupWorldSelection extends GuiScreen {
private GuiButton worldConvert = null;
private GuiButton worldBackup = null;
private long worldSeed;
private boolean oldRNG;
private NBTTagCompound levelDat;
private String worldName;
@ -47,6 +49,7 @@ public class GuiScreenBackupWorldSelection extends GuiScreen {
this.worldName = worldName;
this.levelDat = levelDat;
this.worldSeed = levelDat.getCompoundTag("Data").getLong("RandomSeed");
this.oldRNG = levelDat.getCompoundTag("Data").getInteger("eaglerVersionSerial") == 0;
}
public void initGui() {
@ -62,7 +65,11 @@ public class GuiScreenBackupWorldSelection extends GuiScreen {
this.drawDefaultBackground();
this.drawCenteredString(this.fontRendererObj, I18n.format("singleplayer.backup.title", worldName), this.width / 2, this.height / 5 - 35, 16777215);
this.drawCenteredString(this.fontRendererObj, I18n.format("singleplayer.backup.seed") + " " + worldSeed, this.width / 2, this.height / 5 + 62, 0xAAAAFF);
if(oldRNG) {
this.drawCenteredString(this.fontRendererObj, I18n.format("singleplayer.backup.seed") + " " + worldSeed + " " + EnumChatFormatting.RED + "(pre-u34)", this.width / 2, this.height / 5 + 62, 0xAAAAFF);
}else {
this.drawCenteredString(this.fontRendererObj, I18n.format("singleplayer.backup.seed") + " " + worldSeed, this.width / 2, this.height / 5 + 62, 0xAAAAFF);
}
int toolTipColor = 0xDDDDAA;
if(worldRecreate.isMouseOver()) {
@ -85,8 +92,13 @@ public class GuiScreenBackupWorldSelection extends GuiScreen {
this.mc.displayGuiScreen(selectWorld);
}else if(par1GuiButton.id == 1) {
GuiCreateWorld cw = new GuiCreateWorld(selectWorld);
cw.func_146318_a(new WorldInfo(this.levelDat.getCompoundTag("Data")));
this.mc.displayGuiScreen(cw);
WorldInfo inf = new WorldInfo(this.levelDat.getCompoundTag("Data"));
cw.func_146318_a(inf);
if(inf.isOldEaglercraftRandom()) {
this.mc.displayGuiScreen(new GuiScreenOldSeedWarning(cw));
}else {
this.mc.displayGuiScreen(cw);
}
}else if(par1GuiButton.id == 2) {
this.mc.displayGuiScreen(new GuiRenameWorld(this.selectWorld, this.worldName, true));
}else if(par1GuiButton.id == 3) {

View File

@ -0,0 +1,48 @@
package net.lax1dude.eaglercraft.v1_8.sp.gui;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.resources.I18n;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class GuiScreenOldSeedWarning extends GuiScreen {
private final GuiScreen cont;
public GuiScreenOldSeedWarning(GuiScreen cont) {
this.cont = cont;
}
public void initGui() {
this.buttonList.clear();
this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 6 + 96, I18n.format("singleplayer.oldseedwarning.ok")));
}
public void drawScreen(int par1, int par2, float par3) {
this.drawDefaultBackground();
this.drawCenteredString(fontRendererObj, I18n.format("singleplayer.oldseedwarning.title"), this.width / 2, 70, 11184810);
this.drawCenteredString(fontRendererObj, I18n.format("singleplayer.oldseedwarning.msg1"), this.width / 2, 90, 16777215);
this.drawCenteredString(fontRendererObj, I18n.format("singleplayer.oldseedwarning.msg2"), this.width / 2, 105, 16777215);
super.drawScreen(par1, par2, par3);
}
protected void actionPerformed(GuiButton par1GuiButton) {
if(par1GuiButton.id == 0) {
this.mc.displayGuiScreen(cont);
}
}
}

View File

@ -25,11 +25,11 @@ public class IPCPacketManager {
public static final HashMap<Integer, Supplier<IPCPacketBase>> mappings = new HashMap();
public static final IPCInputStream IPC_INPUT_STREAM = new IPCInputStream();
public static final IPCOutputStream IPC_OUTPUT_STREAM = new IPCOutputStream();
public final IPCInputStream IPC_INPUT_STREAM = new IPCInputStream();
public final IPCOutputStream IPC_OUTPUT_STREAM = new IPCOutputStream();
public static final DataInputStream IPC_DATA_INPUT_STREAM = new DataInputStream(IPC_INPUT_STREAM);
public static final DataOutputStream IPC_DATA_OUTPUT_STREAM = new DataOutputStream(IPC_OUTPUT_STREAM);
public final DataInputStream IPC_DATA_INPUT_STREAM = new DataInputStream(IPC_INPUT_STREAM);
public final DataOutputStream IPC_DATA_OUTPUT_STREAM = new DataOutputStream(IPC_OUTPUT_STREAM);
static {
mappings.put(IPCPacket00StartServer.ID, IPCPacket00StartServer::new);
@ -60,7 +60,7 @@ public class IPCPacketManager {
mappings.put(IPCPacketFFProcessKeepAlive.ID, IPCPacketFFProcessKeepAlive::new);
}
public static byte[] IPCSerialize(IPCPacketBase pkt) throws IOException {
public byte[] IPCSerialize(IPCPacketBase pkt) throws IOException {
IPC_OUTPUT_STREAM.feedBuffer(new byte[pkt.size() + 1], pkt.getClass().getSimpleName());
IPC_OUTPUT_STREAM.write(pkt.id());
@ -69,7 +69,7 @@ public class IPCPacketManager {
return IPC_OUTPUT_STREAM.returnBuffer();
}
public static IPCPacketBase IPCDeserialize(byte[] pkt) throws IOException {
public IPCPacketBase IPCDeserialize(byte[] pkt) throws IOException {
IPC_INPUT_STREAM.feedBuffer(pkt);
int i = IPC_INPUT_STREAM.read();

View File

@ -60,6 +60,8 @@ public class EaglerIntegratedServerWorker {
private static final Map<String, IntegratedServerPlayerNetworkManager> openChannels = new HashMap();
private static final IPCPacketManager packetManagerInstance = new IPCPacketManager();
private static void processAsyncMessageQueue() {
List<IPCPacketData> pktList = ServerPlatformSingleplayer.recieveAllPacket();
if(pktList != null) {
@ -69,7 +71,7 @@ public class EaglerIntegratedServerWorker {
if(packetData.channel.equals(SingleplayerServerController.IPC_CHANNEL)) {
IPCPacketBase ipc;
try {
ipc = IPCPacketManager.IPCDeserialize(packetData.contents);
ipc = packetManagerInstance.IPCDeserialize(packetData.contents);
}catch(IOException ex) {
throw new RuntimeException("Failed to deserialize IPC packet", ex);
}
@ -422,7 +424,7 @@ public class EaglerIntegratedServerWorker {
public static void sendIPCPacket(IPCPacketBase ipc) {
byte[] pkt;
try {
pkt = IPCPacketManager.IPCSerialize(ipc);
pkt = packetManagerInstance.IPCSerialize(ipc);
}catch (IOException ex) {
throw new RuntimeException("Failed to serialize IPC packet", ex);
}

View File

@ -12,6 +12,7 @@ import net.lax1dude.eaglercraft.v1_8.sp.server.EaglerIntegratedServerWorker;
import net.lax1dude.eaglercraft.v1_8.sp.server.EaglerSaveFormat;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.storage.WorldInfo;
/**
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
@ -66,6 +67,9 @@ public class WorldConverterEPK {
NBTTagCompound worldDatNBT = CompressedStreamTools.readCompressed(new EaglerInputStream(b));
worldDatNBT.getCompoundTag("Data").setString("LevelName", newName);
worldDatNBT.getCompoundTag("Data").setLong("LastPlayed", System.currentTimeMillis());
if(has152Format) {
WorldInfo.initEaglerVersion(worldDatNBT.getCompoundTag("Data"));
}
EaglerOutputStream tmp = new EaglerOutputStream();
CompressedStreamTools.writeCompressed(worldDatNBT, tmp);
b = tmp.toByteArray();

View File

@ -20,6 +20,7 @@ import net.lax1dude.eaglercraft.v1_8.sp.server.EaglerChunkLoader;
import net.lax1dude.eaglercraft.v1_8.sp.server.EaglerIntegratedServerWorker;
import net.lax1dude.eaglercraft.v1_8.sp.server.EaglerSaveFormat;
import net.minecraft.world.chunk.storage.RegionFile;
import net.minecraft.world.storage.WorldInfo;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
@ -98,9 +99,9 @@ public class WorldConverterMCA {
gameRulesNBT.setString("colorCodes", s);
gameRulesNBT.setString("doSignEditing", s);
worldDatNBT.getCompoundTag("Data").setTag("GameRules", gameRulesNBT);
worldDatNBT.getCompoundTag("Data").setString("LevelName", newName);
worldDatNBT.getCompoundTag("Data").setLong("LastPlayed", System.currentTimeMillis());
WorldInfo.initEaglerVersion(worldDatNBT.getCompoundTag("Data"));
EaglerOutputStream bo = new EaglerOutputStream();
CompressedStreamTools.writeCompressed(worldDatNBT, bo);
b = bo.toByteArray();

View File

@ -33,8 +33,8 @@ out vec4 v_color4f;
uniform mat4 u_matrixTransform;
uniform vec3 u_texCoordSize2f_particleSize1f;
uniform vec4 u_transformParam_1_2_3_4_f;
uniform float u_transformParam_5_f;
uniform vec3 u_transformParam_1_2_5_f;
uniform vec2 u_transformParam_3_4_f;
uniform vec4 u_color4f;
uniform sampler2D u_lightmapTexture;
@ -51,11 +51,8 @@ void main() {
vec3 pos3f = p_position3f;
vec2 spos2f = a_position2f * particleSize;
pos3f.x += u_transformParam_1_2_3_4_f.x * spos2f.x;
pos3f.x += u_transformParam_1_2_3_4_f.w * spos2f.y;
pos3f.y += u_transformParam_1_2_3_4_f.y * spos2f.y;
pos3f.z += u_transformParam_1_2_3_4_f.z * spos2f.x;
pos3f.z += u_transformParam_5_f * spos2f.y;
pos3f += u_transformParam_1_2_5_f * spos2f.xyy;
pos3f.zx += u_transformParam_3_4_f * spos2f;
gl_Position = u_matrixTransform * vec4(pos3f, 1.0);
}

View File

@ -43,8 +43,8 @@ uniform mat4 u_matrixTransform;
#endif
uniform vec3 u_texCoordSize2f_particleSize1f;
uniform vec4 u_transformParam_1_2_3_4_f;
uniform float u_transformParam_5_f;
uniform vec3 u_transformParam_1_2_5_f;
uniform vec2 u_transformParam_3_4_f;
void main() {
v_color4f = p_color4f.bgra;
@ -59,11 +59,8 @@ void main() {
vec3 pos3f = p_position3f;
vec2 spos2f = a_position2f * particleSize;
pos3f.x += u_transformParam_1_2_3_4_f.x * spos2f.x;
pos3f.x += u_transformParam_1_2_3_4_f.w * spos2f.y;
pos3f.y += u_transformParam_1_2_3_4_f.y * spos2f.y;
pos3f.z += u_transformParam_1_2_3_4_f.z * spos2f.x;
pos3f.z += u_transformParam_5_f * spos2f.y;
pos3f += u_transformParam_1_2_5_f * spos2f.xyy;
pos3f.zx += u_transformParam_3_4_f * spos2f;
#ifdef COMPILE_GBUFFER_VSH
gl_Position = u_matrixTransform * vec4(pos3f, 1.0);

View File

@ -6,4 +6,5 @@ minecraft:torch,0,1.0000,0.5983,0.2655,10.0
minecraft:redstone_torch,0,1.0000,0.1578,0.0000,4.0
minecraft:sea_lantern,0,0.5530,0.6468,1.0000,10.0,
minecraft:lava_bucket,0,1.0000,0.4461,0.1054,6.0,
minecraft:nether_star,0,0.5711,0.6611,1.0000,6.0
minecraft:nether_star,0,0.5711,0.6611,1.0000,6.0
minecraft:ender_eye,0,0.1990,0.7750,0.4130,4.0
1 item,damage,red,green,blue,intensity
6 minecraft:redstone_torch,0,1.0000,0.1578,0.0000,4.0
7 minecraft:sea_lantern,0,0.5530,0.6468,1.0000,10.0,
8 minecraft:lava_bucket,0,1.0000,0.4461,0.1054,6.0,
9 minecraft:nether_star,0,0.5711,0.6611,1.0000,6.0
10 minecraft:ender_eye,0,0.1990,0.7750,0.4130,4.0

View File

@ -1,7 +1,7 @@
{
"name": "§eHigh Performance PBR",
"desc": "Pack made from scratch specifically for this client, designed to give what I call the best balance between quality and performance possible in a browser but obviously that's just my opinion",
"vers": "1.1.0",
"vers": "1.2.0",
"author": "lax1dude",
"api_vers": 1,
"features": [

View File

@ -0,0 +1,67 @@
#line 2
/*
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
precision lowp int;
precision mediump float;
precision mediump sampler2D;
in vec4 v_position4f;
in vec2 v_texCoord2f;
in vec4 v_color4f;
in vec2 v_lightmap2f;
layout(location = 0) out vec4 output4f;
uniform sampler2D u_inputTexture;
uniform sampler2D u_lightmapTexture;
uniform mat4 u_inverseViewMatrix4f;
layout(std140) uniform u_chunkLightingData {
mediump int u_dynamicLightCount1i;
mediump int _paddingA_;
mediump int _paddingB_;
mediump int _paddingC_;
mediump vec4 u_dynamicLightArray[12];
};
void main() {
vec4 color = texture(u_inputTexture, v_texCoord2f) * v_color4f;
if(color.a < 0.004) {
discard;
}
vec4 light;
float diffuse = 0.0;
if(u_dynamicLightCount1i > 0) {
vec4 worldPosition4f = u_inverseViewMatrix4f * v_position4f;
worldPosition4f.xyz /= worldPosition4f.w;
vec3 normalVector3f = normalize(u_inverseViewMatrix4f[2].xyz);
int safeLightCount = u_dynamicLightCount1i > 12 ? 0 : u_dynamicLightCount1i;
for(int i = 0; i < safeLightCount; ++i) {
light = u_dynamicLightArray[i];
light.xyz = light.xyz - worldPosition4f.xyz;
diffuse += max(dot(normalize(light.xyz), normalVector3f) * 0.8 + 0.2, 0.0) * max(light.w - sqrt(dot(light.xyz, light.xyz)), 0.0);
}
}
color *= texture(u_lightmapTexture, vec2(min(v_lightmap2f.x + diffuse * 0.066667, 1.0), v_lightmap2f.y));
output4f = color;
}

View File

@ -0,0 +1,61 @@
#line 2
/*
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
precision lowp int;
precision highp float;
precision mediump sampler2D;
layout(location = 0) in vec2 a_position2f;
layout(location = 1) in vec3 p_position3f;
layout(location = 2) in vec2 p_texCoords2i;
layout(location = 3) in vec2 p_lightMap2f;
layout(location = 4) in vec2 p_particleSize_texCoordsSize_2i;
layout(location = 5) in vec4 p_color4f;
out vec4 v_position4f;
out vec2 v_texCoord2f;
out vec4 v_color4f;
out vec2 v_lightmap2f;
uniform mat4 u_modelViewMatrix4f;
uniform mat4 u_projectionMatrix4f;
uniform vec3 u_texCoordSize2f_particleSize1f;
uniform vec3 u_transformParam_1_2_5_f;
uniform vec2 u_transformParam_3_4_f;
uniform vec4 u_color4f;
void main() {
v_color4f = u_color4f * p_color4f.bgra;
v_lightmap2f = p_lightMap2f;
vec2 tex2f = a_position2f * 0.5 + 0.5;
tex2f.y = 1.0 - tex2f.y;
tex2f = p_texCoords2i + tex2f * p_particleSize_texCoordsSize_2i.y;
v_texCoord2f = tex2f * u_texCoordSize2f_particleSize1f.xy;
float particleSize = u_texCoordSize2f_particleSize1f.z * p_particleSize_texCoordsSize_2i.x;
vec3 pos3f = p_position3f;
vec2 spos2f = a_position2f * particleSize;
pos3f += u_transformParam_1_2_5_f * spos2f.xyy;
pos3f.zx += u_transformParam_3_4_f * spos2f;
v_position4f = u_modelViewMatrix4f * vec4(pos3f, 1.0);
gl_Position = u_projectionMatrix4f * v_position4f;
}

View File

@ -0,0 +1,210 @@
#line 2
/*
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
in vec4 v_position4f;
#ifdef COMPILE_TEXTURE_ATTRIB
in vec2 v_texture2f;
#endif
uniform vec4 u_color4f;
#ifdef COMPILE_BLEND_ADD
uniform vec4 u_colorBlendSrc4f;
uniform vec4 u_colorBlendAdd4f;
#endif
#ifdef COMPILE_COLOR_ATTRIB
in vec4 v_color4f;
#endif
#ifdef COMPILE_NORMAL_ATTRIB
in vec3 v_normal3f;
#endif
#ifdef COMPILE_LIGHTMAP_ATTRIB
in vec2 v_lightmap2f;
#endif
#ifdef COMPILE_ENABLE_TEXTURE2D
uniform sampler2D u_samplerTexture;
#if !defined(COMPILE_TEXTURE_ATTRIB) && !defined(COMPILE_ENABLE_TEX_GEN)
uniform vec2 u_textureCoords01;
#endif
#endif
#ifdef COMPILE_ENABLE_LIGHTMAP
uniform sampler2D u_samplerLightmap;
#ifndef COMPILE_LIGHTMAP_ATTRIB
uniform vec2 u_textureCoords02;
#endif
#endif
#ifdef COMPILE_ENABLE_ALPHA_TEST
uniform float u_alphaTestRef1f;
#endif
#ifdef COMPILE_ENABLE_MC_LIGHTING
uniform int u_lightsEnabled1i;
uniform vec4 u_lightsDirections4fv[4];
uniform vec3 u_lightsAmbient3f;
#endif
#ifndef COMPILE_NORMAL_ATTRIB
uniform vec3 u_uniformNormal3f;
#endif
#ifdef COMPILE_ENABLE_FOG
uniform vec4 u_fogParameters4f;
uniform vec4 u_fogColor4f;
#endif
#ifdef COMPILE_ENABLE_TEX_GEN
in vec3 v_objectPosition3f;
uniform ivec4 u_texGenPlane4i;
uniform vec4 u_texGenS4f;
uniform vec4 u_texGenT4f;
uniform vec4 u_texGenR4f;
uniform vec4 u_texGenQ4f;
uniform mat4 u_textureMat4f01;
#endif
#ifdef COMPILE_ENABLE_ANISOTROPIC_FIX
uniform vec2 u_textureAnisotropicFix;
#endif
uniform mat4 u_inverseViewMatrix4f;
layout(std140) uniform u_chunkLightingData {
mediump int u_dynamicLightCount1i;
mediump int _paddingA_;
mediump int _paddingB_;
mediump int _paddingC_;
mediump vec4 u_dynamicLightArray[12];
};
layout(location = 0) out vec4 output4f;
void main() {
#ifdef COMPILE_COLOR_ATTRIB
vec4 color = v_color4f * u_color4f;
#else
vec4 color = u_color4f;
#endif
#ifdef COMPILE_ENABLE_TEX_GEN
vec4 texGenVector;
vec4 texGenPosSrc[2];
texGenPosSrc[0] = vec4(v_objectPosition3f, 1.0);
texGenPosSrc[1] = v_position4f;
texGenVector.x = dot(texGenPosSrc[u_texGenPlane4i.x], u_texGenS4f);
texGenVector.y = dot(texGenPosSrc[u_texGenPlane4i.y], u_texGenT4f);
texGenVector.z = dot(texGenPosSrc[u_texGenPlane4i.z], u_texGenR4f);
texGenVector.w = dot(texGenPosSrc[u_texGenPlane4i.w], u_texGenQ4f);
texGenVector = u_textureMat4f01 * texGenVector;
color *= texture(u_samplerTexture, texGenVector.xy / texGenVector.w);
#ifdef COMPILE_ENABLE_ALPHA_TEST
if(color.a < u_alphaTestRef1f) discard;
#endif
#else
#ifdef COMPILE_ENABLE_TEXTURE2D
#ifdef COMPILE_TEXTURE_ATTRIB
#ifdef COMPILE_ENABLE_ANISOTROPIC_FIX
// d3d11 doesn't support GL_NEAREST upscaling with anisotropic
// filtering enabled, so it needs this stupid fix to 'work'
vec2 uv = floor(v_texture2f * u_textureAnisotropicFix) + 0.5;
color *= texture(u_samplerTexture, uv / u_textureAnisotropicFix);
#else
color *= texture(u_samplerTexture, v_texture2f);
#endif
#else
color *= texture(u_samplerTexture, u_textureCoords01);
#endif
#endif
#ifdef COMPILE_NORMAL_ATTRIB
vec3 normal = normalize(v_normal3f);
#else
vec3 normal = u_uniformNormal3f;
#endif
#ifdef COMPILE_ENABLE_LIGHTMAP
float diffuse = 0.0;
vec4 light;
if(u_dynamicLightCount1i > 0) {
vec4 worldPosition4f = u_inverseViewMatrix4f * v_position4f;
worldPosition4f.xyz /= worldPosition4f.w;
vec3 normalVector3f = normalize(mat3(u_inverseViewMatrix4f) * normal);
int safeLightCount = u_dynamicLightCount1i > 12 ? 0 : u_dynamicLightCount1i;
for(int i = 0; i < safeLightCount; ++i) {
light = u_dynamicLightArray[i];
light.xyz = light.xyz - worldPosition4f.xyz;
diffuse += max(dot(normalize(light.xyz), normalVector3f) * 0.8 + 0.2, 0.0) * max(light.w - sqrt(dot(light.xyz, light.xyz)), 0.0);
}
}
#ifdef COMPILE_LIGHTMAP_ATTRIB
color *= texture(u_samplerLightmap, vec2(min(v_lightmap2f.x + diffuse * 0.066667, 1.0), v_lightmap2f.y));
#else
color *= texture(u_samplerLightmap, vec2(min(u_textureCoords02.x + diffuse * 0.066667, 1.0), u_textureCoords02.y));
#endif
#endif
#ifdef COMPILE_BLEND_ADD
color = color * u_colorBlendSrc4f + u_colorBlendAdd4f;
#endif
#ifdef COMPILE_ENABLE_ALPHA_TEST
if(color.a < u_alphaTestRef1f) discard;
#endif
#endif
#ifdef COMPILE_ENABLE_MC_LIGHTING
#ifndef COMPILE_ENABLE_LIGHTMAP
vec4 light;
float diffuse = 0.0;
#else
diffuse = 0.0;
#endif
for(int i = 0; i < u_lightsEnabled1i; ++i) {
light = u_lightsDirections4fv[i];
diffuse += max(dot(light.xyz, normal), 0.0) * light.w;
}
color.rgb *= min(u_lightsAmbient3f + vec3(diffuse), 1.0);
#endif
#ifdef COMPILE_ENABLE_FOG
vec3 fogPos = v_position4f.xyz / v_position4f.w;
float dist = sqrt(dot(fogPos, fogPos));
float fogDensity = u_fogParameters4f.y;
float fogStart = u_fogParameters4f.z;
float fogEnd = u_fogParameters4f.w;
float f = u_fogParameters4f.x > 0.0 ? 1.0 - exp(-fogDensity * dist) :
(dist - fogStart) / (fogEnd - fogStart);
color.rgb = mix(color.rgb, u_fogColor4f.rgb, clamp(f, 0.0, 1.0) * u_fogColor4f.a);
#endif
output4f = color;
}

View File

@ -0,0 +1,80 @@
#line 2
/*
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
in vec3 a_position3f;
out vec4 v_position4f;
#ifdef COMPILE_ENABLE_TEX_GEN
out vec3 v_objectPosition3f;
#endif
#ifdef COMPILE_TEXTURE_ATTRIB
in vec2 a_texture2f;
out vec2 v_texture2f;
uniform mat4 u_textureMat4f01;
#endif
#ifdef COMPILE_COLOR_ATTRIB
in vec4 a_color4f;
out vec4 v_color4f;
#endif
#ifdef COMPILE_NORMAL_ATTRIB
in vec4 a_normal4f;
out vec3 v_normal3f;
#endif
#ifdef COMPILE_LIGHTMAP_ATTRIB
in vec2 a_lightmap2f;
out vec2 v_lightmap2f;
uniform mat4 u_textureMat4f02;
#endif
uniform mat4 u_modelviewMat4f;
uniform mat4 u_projectionMat4f;
#define TEX_MAT3(mat4In) mat3(mat4In[0].xyw,mat4In[1].xyw,mat4In[3].xyw)
void main() {
#ifdef COMPILE_ENABLE_TEX_GEN
v_objectPosition3f = a_position3f;
#endif
v_position4f = u_modelviewMat4f * vec4(a_position3f, 1.0);
#ifdef COMPILE_TEXTURE_ATTRIB
vec3 v_textureTmp3f = TEX_MAT3(u_textureMat4f01) * vec3(a_texture2f, 1.0);
v_texture2f = v_textureTmp3f.xy / v_textureTmp3f.z;
#endif
#ifdef COMPILE_COLOR_ATTRIB
v_color4f = a_color4f;
#endif
#ifdef COMPILE_NORMAL_ATTRIB
v_normal3f = normalize(mat3(u_modelviewMat4f) * a_normal4f.xyz);
#endif
#ifdef COMPILE_LIGHTMAP_ATTRIB
vec3 v_lightmapTmp3f = TEX_MAT3(u_textureMat4f02) * vec3(a_lightmap2f, 1.0);
v_lightmap2f = v_lightmapTmp3f.xy / v_lightmapTmp3f.z;
#endif
gl_Position = u_projectionMat4f * v_position4f;
}

View File

@ -0,0 +1,9 @@
THESE ARE NOT DOOM/GMOD MODELS!
The FNAW skins are stored in a proprietary format created by lax1dude.
The format is a container for raw OpenGL vertex buffer and index buffer data intended to be copied directly into the GPU's memory, along with a small amount of metadata.
Data is rendered in GL_TRIANGLES mode using glDrawElements.
See "net/lax1dude/eaglercraft/v1_8/opengl/EaglerMeshLoader.java" and "net/lax1dude/eaglercraft/v1_8/opengl/HighPolyMesh.java" for more details.

View File

@ -1 +1 @@
{"pluginName":"EaglercraftXBungee","pluginVersion":"1.2.3","pluginButton":"Download \"EaglerXBungee-1.2.3.jar\"","pluginFilename":"EaglerXBungee.zip"}
{"pluginName":"EaglercraftXBungee","pluginVersion":"1.2.5","pluginButton":"Download \"EaglerXBungee-1.2.5.jar\"","pluginFilename":"EaglerXBungee.zip"}