diff --git a/desktopRuntime/resources/EPKVersionIdentifier.txt b/desktopRuntime/resources/EPKVersionIdentifier.txt index 41915701..471a6eb2 100755 --- a/desktopRuntime/resources/EPKVersionIdentifier.txt +++ b/desktopRuntime/resources/EPKVersionIdentifier.txt @@ -1 +1 @@ -u52 \ No newline at end of file +u53 \ No newline at end of file diff --git a/desktopRuntime/resources/assets/eagler/glsl/core.fsh b/desktopRuntime/resources/assets/eagler/glsl/core.fsh index 43c0e008..3d999a7e 100755 --- a/desktopRuntime/resources/assets/eagler/glsl/core.fsh +++ b/desktopRuntime/resources/assets/eagler/glsl/core.fsh @@ -63,7 +63,7 @@ uniform float u_alphaTestRef1f; #ifdef COMPILE_ENABLE_MC_LIGHTING uniform int u_lightsEnabled1i; -uniform vec4 u_lightsDirections4fv[4]; +uniform vec4 u_lightsDirections4fv[2]; uniform vec3 u_lightsAmbient3f; #ifndef COMPILE_NORMAL_ATTRIB uniform vec3 u_uniformNormal3f; @@ -166,20 +166,14 @@ void main() { #else vec3 normal = u_uniformNormal3f; #endif - float diffuse = 0.0; vec4 light; -#ifdef EAGLER_HAS_GLES_300 - for(int i = 0; i < u_lightsEnabled1i; ++i) { -#else - for(int i = 0; i < 4; ++i) { -#endif - light = u_lightsDirections4fv[i]; - diffuse += max(dot(light.xyz, normal), 0.0) * light.w; -#ifndef EAGLER_HAS_GLES_300 - if(i + 1 >= u_lightsEnabled1i) { + float diffuse = 0.0; + for(int i = 0; i < 2; ++i) { + if(i >= u_lightsEnabled1i) { break; } -#endif + light = u_lightsDirections4fv[i]; + diffuse += max(dot(light.xyz, normal), 0.0) * light.w; } color.rgb *= min(u_lightsAmbient3f + vec3(diffuse), 1.0); #endif diff --git a/desktopRuntime/resources/assets/eagler/glsl/dynamiclights/accel_particle_dynamiclights.fsh b/desktopRuntime/resources/assets/eagler/glsl/dynamiclights/accel_particle_dynamiclights.fsh index 524e3149..6eb67257 100755 --- a/desktopRuntime/resources/assets/eagler/glsl/dynamiclights/accel_particle_dynamiclights.fsh +++ b/desktopRuntime/resources/assets/eagler/glsl/dynamiclights/accel_particle_dynamiclights.fsh @@ -20,7 +20,6 @@ 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; @@ -30,16 +29,6 @@ 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; @@ -47,20 +36,7 @@ void main() { discard; } - vec4 dlight; - float blockLight = v_lightmap2f.x; - if(u_dynamicLightCount1i > 0) { - vec4 worldPosition4f = u_inverseViewMatrix4f * v_position4f; - worldPosition4f.xyz /= worldPosition4f.w; - int safeLightCount = u_dynamicLightCount1i > 12 ? 0 : u_dynamicLightCount1i; - for(int i = 0; i < safeLightCount; ++i) { - dlight = u_dynamicLightArray[i]; - dlight.xyz = dlight.xyz - worldPosition4f.xyz; - blockLight = max((dlight.w - length(dlight.xyz)) * 0.066667, blockLight); - } - } - - color *= texture(u_lightmapTexture, vec2(blockLight, v_lightmap2f.y)); + color *= texture(u_lightmapTexture, v_lightmap2f); output4f = color; } diff --git a/desktopRuntime/resources/assets/eagler/glsl/dynamiclights/accel_particle_dynamiclights.vsh b/desktopRuntime/resources/assets/eagler/glsl/dynamiclights/accel_particle_dynamiclights.vsh index 2ff13dd2..f00974a5 100755 --- a/desktopRuntime/resources/assets/eagler/glsl/dynamiclights/accel_particle_dynamiclights.vsh +++ b/desktopRuntime/resources/assets/eagler/glsl/dynamiclights/accel_particle_dynamiclights.vsh @@ -28,21 +28,27 @@ 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 mat4 u_inverseViewMatrix4f; uniform vec3 u_texCoordSize2f_particleSize1f; uniform vec3 u_transformParam_1_2_5_f; uniform vec2 u_transformParam_3_4_f; uniform vec4 u_color4f; +layout(std140) uniform u_chunkLightingData { + mediump uvec2 u_dynamicLightOffsetCount2i; + mediump int _paddingA_; + mediump int _paddingB_; + mediump uvec4 u_dynamicLightArray[4]; +}; + 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; @@ -56,6 +62,40 @@ void main() { 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; + vec4 pos4f = u_modelViewMatrix4f * vec4(pos3f, 1.0); + gl_Position = u_projectionMatrix4f * pos4f; + + float blockLight = 0.0; + + vec4 dlight; + uvec4 dlighti1, dlighti2; + if(u_dynamicLightOffsetCount2i.y > 0u) { + vec3 dlightOffset = vec3(ivec3( + int(u_dynamicLightOffsetCount2i.x << 16), + int(u_dynamicLightOffsetCount2i.x << 8), + int(u_dynamicLightOffsetCount2i.x) + ) >> 24); + vec4 worldPosition4f = u_inverseViewMatrix4f * pos4f; + worldPosition4f.xyz = worldPosition4f.xyz / worldPosition4f.w + dlightOffset; + for(uint i = 0u; i < 4u; ++i) { + dlighti1 = u_dynamicLightArray[i]; + dlighti2 = dlighti1 << 16; + + dlight = vec4(ivec4(ivec2(dlighti2.xy), ivec2(dlighti1.xy)) >> 16) * 0.0009765923; + dlight.xyz = dlight.xyz - worldPosition4f.xyz; + blockLight = max((dlight.w - length(dlight.xyz)) * 0.066667, blockLight); + if(i * 2u + 1u >= u_dynamicLightOffsetCount2i.y) { + break; + } + + dlight = vec4(ivec4(ivec2(dlighti2.zw), ivec2(dlighti1.zw)) >> 16) * 0.0009765923; + dlight.xyz = dlight.xyz - worldPosition4f.xyz; + blockLight = max((dlight.w - length(dlight.xyz)) * 0.066667, blockLight); + if(i * 2u + 2u >= u_dynamicLightOffsetCount2i.y) { + break; + } + } + } + + v_lightmap2f = vec2(max(p_lightMap2f.x, blockLight), p_lightMap2f.y); } diff --git a/desktopRuntime/resources/assets/eagler/glsl/dynamiclights/core_dynamiclights.fsh b/desktopRuntime/resources/assets/eagler/glsl/dynamiclights/core_dynamiclights.fsh index 454b69b8..7255fafa 100755 --- a/desktopRuntime/resources/assets/eagler/glsl/dynamiclights/core_dynamiclights.fsh +++ b/desktopRuntime/resources/assets/eagler/glsl/dynamiclights/core_dynamiclights.fsh @@ -16,7 +16,9 @@ * */ +#if defined(COMPILE_ENABLE_TEX_GEN) || defined(COMPILE_ENABLE_FOG) in vec4 v_position4f; +#endif #ifdef COMPILE_TEXTURE_ATTRIB in vec2 v_texture2f; @@ -61,7 +63,7 @@ uniform float u_alphaTestRef1f; #ifdef COMPILE_ENABLE_MC_LIGHTING uniform int u_lightsEnabled1i; -uniform vec4 u_lightsDirections4fv[4]; +uniform vec4 u_lightsDirections4fv[2]; uniform vec3 u_lightsAmbient3f; #endif @@ -88,15 +90,9 @@ uniform mat4 u_textureMat4f01; 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]; -}; +#ifdef COMPILE_ENABLE_LIGHTMAP +in float v_dynamicLight1f; +#endif layout(location = 0) out vec4 output4f; @@ -151,17 +147,9 @@ void main() { #else float blockLight = u_textureCoords02.x; #endif - vec4 dlight; - if(u_dynamicLightCount1i > 0) { - vec4 worldPosition4f = u_inverseViewMatrix4f * v_position4f; - worldPosition4f.xyz /= worldPosition4f.w; - int safeLightCount = u_dynamicLightCount1i > 12 ? 0 : u_dynamicLightCount1i; - for(int i = 0; i < safeLightCount; ++i) { - dlight = u_dynamicLightArray[i]; - dlight.xyz = dlight.xyz - worldPosition4f.xyz; - blockLight = max((dlight.w - length(dlight.xyz)) * 0.066667, blockLight); - } - } + + blockLight = max(blockLight, v_dynamicLight1f); + #ifdef COMPILE_LIGHTMAP_ATTRIB color *= texture(u_samplerLightmap, vec2(blockLight, v_lightmap2f.y)); #else @@ -179,16 +167,18 @@ void main() { #endif +#ifdef COMPILE_ENABLE_MC_LIGHTING #ifdef COMPILE_NORMAL_ATTRIB vec3 normal = v_normal3f; #else vec3 normal = u_uniformNormal3f; #endif - -#ifdef COMPILE_ENABLE_MC_LIGHTING vec4 light; float diffuse = 0.0; - for(int i = 0; i < u_lightsEnabled1i; ++i) { + for(int i = 0; i < 2; ++i) { + if(i >= u_lightsEnabled1i) { + break; + } light = u_lightsDirections4fv[i]; diffuse += max(dot(light.xyz, normal), 0.0) * light.w; } diff --git a/desktopRuntime/resources/assets/eagler/glsl/dynamiclights/core_dynamiclights.vsh b/desktopRuntime/resources/assets/eagler/glsl/dynamiclights/core_dynamiclights.vsh index b1cb7f3d..cc8384b6 100755 --- a/desktopRuntime/resources/assets/eagler/glsl/dynamiclights/core_dynamiclights.vsh +++ b/desktopRuntime/resources/assets/eagler/glsl/dynamiclights/core_dynamiclights.vsh @@ -18,7 +18,13 @@ in vec3 a_position3f; +#if defined(COMPILE_ENABLE_TEX_GEN) || defined(COMPILE_ENABLE_FOG) +#define _COMPILE_VARYING_POSITION +#endif + +#ifdef _COMPILE_VARYING_POSITION out vec4 v_position4f; +#endif #ifdef COMPILE_ENABLE_TEX_GEN out vec3 v_objectPosition3f; @@ -46,16 +52,32 @@ out vec2 v_lightmap2f; uniform mat4 u_textureMat4f02; #endif +#ifdef COMPILE_ENABLE_LIGHTMAP +out float v_dynamicLight1f; +#endif + uniform mat4 u_modelviewMat4f; uniform mat4 u_projectionMat4f; +uniform mat4 u_inverseViewMatrix4f; #define TEX_MAT3(mat4In) mat3(mat4In[0].xyw,mat4In[1].xyw,mat4In[3].xyw) +layout(std140) uniform u_chunkLightingData { + mediump uvec2 u_dynamicLightOffsetCount2i; + mediump int _paddingA_; + mediump int _paddingB_; + mediump uvec4 u_dynamicLightArray[4]; +}; + void main() { #ifdef COMPILE_ENABLE_TEX_GEN v_objectPosition3f = a_position3f; #endif +#ifndef _COMPILE_VARYING_POSITION + vec4 v_position4f; +#endif + v_position4f = u_modelviewMat4f * vec4(a_position3f, 1.0); #ifdef COMPILE_TEXTURE_ATTRIB @@ -75,6 +97,42 @@ void main() { 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; + +#ifdef COMPILE_ENABLE_LIGHTMAP + float blockLight = 0.0; + + vec4 dlight; + uvec4 dlighti1, dlighti2; + if(u_dynamicLightOffsetCount2i.y > 0u) { + vec3 dlightOffset = vec3(ivec3( + int(u_dynamicLightOffsetCount2i.x << 16), + int(u_dynamicLightOffsetCount2i.x << 8), + int(u_dynamicLightOffsetCount2i.x) + ) >> 24); + vec4 worldPosition4f = u_inverseViewMatrix4f * v_position4f; + worldPosition4f.xyz = worldPosition4f.xyz / worldPosition4f.w + dlightOffset; + for(uint i = 0u; i < 4u; ++i) { + dlighti1 = u_dynamicLightArray[i]; + dlighti2 = dlighti1 << 16; + + dlight = vec4(ivec4(ivec2(dlighti2.xy), ivec2(dlighti1.xy)) >> 16) * 0.0009765923; + dlight.xyz = dlight.xyz - worldPosition4f.xyz; + blockLight = max((dlight.w - length(dlight.xyz)) * 0.066667, blockLight); + if(i * 2u + 1u >= u_dynamicLightOffsetCount2i.y) { + break; + } + + dlight = vec4(ivec4(ivec2(dlighti2.zw), ivec2(dlighti1.zw)) >> 16) * 0.0009765923; + dlight.xyz = dlight.xyz - worldPosition4f.xyz; + blockLight = max((dlight.w - length(dlight.xyz)) * 0.066667, blockLight); + if(i * 2u + 2u >= u_dynamicLightOffsetCount2i.y) { + break; + } + } + } + + v_dynamicLight1f = blockLight; +#endif } diff --git a/desktopRuntime/resources/assets/eagler/silence_loop.wav b/desktopRuntime/resources/assets/eagler/silence_loop.wav index d1eee0e8..e3a005ef 100755 Binary files a/desktopRuntime/resources/assets/eagler/silence_loop.wav and b/desktopRuntime/resources/assets/eagler/silence_loop.wav differ diff --git a/desktopRuntime/resources/assets/minecraft/lang/en_US.lang b/desktopRuntime/resources/assets/minecraft/lang/en_US.lang index 56ebe652..5a5cc79b 100755 --- a/desktopRuntime/resources/assets/minecraft/lang/en_US.lang +++ b/desktopRuntime/resources/assets/minecraft/lang/en_US.lang @@ -219,10 +219,6 @@ eaglercraft.shaders.gui.option.SCREEN_SPACE_REFLECTIONS.desc.4=Both raymarching eaglercraft.shaders.gui.option.SCREEN_SPACE_REFLECTIONS.desc.6=ON: enable raytracing (slower) eaglercraft.shaders.gui.option.SCREEN_SPACE_REFLECTIONS.desc.7=OFF: disable raytracing (faster) -eaglercraft.shaders.gui.option.LIGHT_SHAFTS.desc.0=Render god rays (light shafts) for sunlight and moonlight shadows -eaglercraft.shaders.gui.option.LIGHT_SHAFTS.desc.2=ON: render god rays (slower) -eaglercraft.shaders.gui.option.LIGHT_SHAFTS.desc.3=OFF: disable god rays (faster) - eaglercraft.shaders.gui.option.POST_LENS_DISTORION.label=Lens Distort eaglercraft.shaders.gui.option.POST_LENS_DISTORION.desc.0=Renders chromatic abberation and lens distorion diff --git a/src/game/java/net/minecraft/client/Minecraft.java b/src/game/java/net/minecraft/client/Minecraft.java index a8b1cb0b..8f410dcc 100755 --- a/src/game/java/net/minecraft/client/Minecraft.java +++ b/src/game/java/net/minecraft/client/Minecraft.java @@ -880,7 +880,6 @@ public class Minecraft implements IThreadListener { GlStateManager.viewport(0, 0, this.displayWidth, this.displayHeight); GlStateManager.clearColor(0.0f, 0.0f, 0.0f, 1.0f); GlStateManager.pushMatrix(); - GlStateManager.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); GlStateManager.enableTexture2D(); if (this.thePlayer != null && this.thePlayer.isEntityInsideOpaqueBlock()) { this.gameSettings.thirdPersonView = 0; diff --git a/src/game/java/net/minecraft/client/renderer/entity/RenderFallingBlock.java b/src/game/java/net/minecraft/client/renderer/entity/RenderFallingBlock.java index d4d2da97..0c0f147b 100755 --- a/src/game/java/net/minecraft/client/renderer/entity/RenderFallingBlock.java +++ b/src/game/java/net/minecraft/client/renderer/entity/RenderFallingBlock.java @@ -4,7 +4,6 @@ import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager; import net.lax1dude.eaglercraft.v1_8.opengl.VertexFormat; import net.lax1dude.eaglercraft.v1_8.opengl.WorldRenderer; import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.DeferredStateManager; -import net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights.DynamicLightsStateManager; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; diff --git a/src/game/java/net/minecraft/crash/CrashReport.java b/src/game/java/net/minecraft/crash/CrashReport.java index 6d2e24b8..54c6b02f 100755 --- a/src/game/java/net/minecraft/crash/CrashReport.java +++ b/src/game/java/net/minecraft/crash/CrashReport.java @@ -167,6 +167,15 @@ public class CrashReport { stackTrace.append("\tat ").append(s).append('\n'); }); + Throwable t = this.cause.getCause(); + while (t != null) { + stackTrace.append("Caused by: " + t.toString()).append('\n'); + EagRuntime.getStackTrace(t, (s) -> { + stackTrace.append("\tat ").append(s).append('\n'); + }); + t = t.getCause(); + } + return stackTrace.toString(); } diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformOpenGL.java b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformOpenGL.java index 4f7bfbf3..d9d1a3e7 100755 --- a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformOpenGL.java +++ b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformOpenGL.java @@ -573,6 +573,10 @@ public class PlatformOpenGL { glDrawElements(mode, count, type, offset); } + public static void _wglDrawRangeElements(int mode, int start, int end, int count, int type, int offset) { + glDrawRangeElements(mode, start, end, count, type, offset); + } + public static void _wglDrawElementsInstanced(int mode, int count, int type, int offset, int instanced) { switch(instancingImpl) { case INSTANCE_IMPL_CORE: diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/EaglercraftVersion.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/EaglercraftVersion.java index c9e0fb5a..7bd92a22 100755 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/EaglercraftVersion.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/EaglercraftVersion.java @@ -10,7 +10,7 @@ public class EaglercraftVersion { /// Customize these to fit your fork: public static final String projectForkName = "EaglercraftX"; - public static final String projectForkVersion = "u52"; + public static final String projectForkVersion = "u53"; public static final String projectForkVendor = "lax1dude"; public static final String projectForkURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8"; @@ -20,20 +20,20 @@ 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 = "u52"; + public static final String projectOriginVersion = "u53"; public static final String projectOriginURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8"; // rest in peace // EPK Version Identifier - public static final String EPKVersionIdentifier = "u52"; // Set to null to disable EPK version check + public static final String EPKVersionIdentifier = "u53"; // Set to null to disable EPK version check // Updating configuration public static final boolean enableUpdateService = true; public static final String updateBundlePackageName = "net.lax1dude.eaglercraft.v1_8.client"; - public static final int updateBundlePackageVersionInt = 52; + public static final int updateBundlePackageVersionInt = 53; public static final String updateLatestLocalStorageKey = "latestUpdate_" + updateBundlePackageName; diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/mojang/authlib/GameProfile.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/mojang/authlib/GameProfile.java index 73890bf4..073f6987 100755 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/mojang/authlib/GameProfile.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/mojang/authlib/GameProfile.java @@ -19,7 +19,6 @@ package net.lax1dude.eaglercraft.v1_8.mojang.authlib; import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.builder.ToStringBuilder; import com.google.common.collect.Multimap; import com.google.common.collect.MultimapBuilder; diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/mojang/authlib/TexturesProperty.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/mojang/authlib/TexturesProperty.java index 9f635175..3f6ed45d 100755 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/mojang/authlib/TexturesProperty.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/mojang/authlib/TexturesProperty.java @@ -94,7 +94,7 @@ public class TexturesProperty { if(meta != null) { String modelStr = meta.optString("model"); if(modelStr != null && modelStr.equalsIgnoreCase("slim")) { - model = SkinModel.STEVE; + model = SkinModel.ALEX; } } } diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/DisplayList.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/DisplayList.java index 750fbac7..e88f0d99 100755 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/DisplayList.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/DisplayList.java @@ -26,7 +26,6 @@ class DisplayList { int attribs = -1; int mode = -1; int count = 0; - boolean bindQuad16 = false; - boolean bindQuad32 = false; + byte bindQuad = 0; } \ No newline at end of file diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/EaglercraftGPU.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/EaglercraftGPU.java index 6c43112c..c6d22090 100755 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/EaglercraftGPU.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/EaglercraftGPU.java @@ -40,7 +40,7 @@ import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*; public class EaglercraftGPU { - static final GLObjectRecycler arrayBufferRecycler = new GLObjectRecycler(32) { + static final GLObjectRecycler arrayBufferRecycler = new GLObjectRecycler(256) { @Override protected IBufferGL create() { @@ -49,7 +49,14 @@ public class EaglercraftGPU { @Override protected void invalidate(IBufferGL object) { - // Don't bother + IBufferGL old = currentArrayBuffer; + if (old != object) { + _wglBindBuffer(GL_ARRAY_BUFFER, object); + } + _wglBufferData(GL_ARRAY_BUFFER, 0, GL_STATIC_DRAW); + if (old != object) { + _wglBindBuffer(GL_ARRAY_BUFFER, old); + } } @Override @@ -59,7 +66,7 @@ public class EaglercraftGPU { }; - static final GLObjectRecycler elementArrayBufferRecycler = new GLObjectRecycler(32) { + static final GLObjectRecycler elementArrayBufferRecycler = new GLObjectRecycler(256) { @Override protected IBufferGL create() { @@ -68,7 +75,22 @@ public class EaglercraftGPU { @Override protected void invalidate(IBufferGL object) { - // Don't bother + IVertexArrayGL oldArray = currentVertexArray; + boolean vao = !emulatedVAOs; + if (vao && vertexArrayCapable && oldArray != null) { + _wglBindVertexArray(null); + } + IBufferGL old = currentEmulatedVAOIndexBuffer; + if (vao || old != object) { + _wglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object); + } + _wglBufferData(GL_ELEMENT_ARRAY_BUFFER, 0, GL_STATIC_DRAW); + if (!vao && old != object) { + _wglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, old); + } + if (vao && vertexArrayCapable && oldArray != null) { + _wglBindVertexArray(oldArray); + } } @Override @@ -211,8 +233,7 @@ public class EaglercraftGPU { if(dp.vertexArray == null) { dp.vertexArray = createGLVertexArray(); - dp.bindQuad16 = false; - dp.bindQuad32 = false; + dp.bindQuad = 0; } if(dp.vertexBuffer == null) { dp.vertexBuffer = createGLArrayBuffer(); @@ -252,8 +273,7 @@ public class EaglercraftGPU { if(dp.vertexArray == null) { dp.vertexArray = createGLVertexArray(); - dp.bindQuad16 = false; - dp.bindQuad32 = false; + dp.bindQuad = 0; } if(dp.vertexBuffer == null) { dp.vertexBuffer = createGLArrayBuffer(); @@ -280,21 +300,19 @@ public class EaglercraftGPU { if(dp.mode == GL_QUADS) { int cnt = dp.count; if(cnt > quad16MaxVertices) { - if(!dp.bindQuad32) { - dp.bindQuad16 = false; - dp.bindQuad32 = true; + if(dp.bindQuad != 32) { + dp.bindQuad = 32; attachQuad32EmulationBuffer(cnt, true); }else { attachQuad32EmulationBuffer(cnt, false); } - p.drawElements(GL_TRIANGLES, (cnt >> 2) * 6, GL_UNSIGNED_INT, 0); + p.drawRangeElements(GL_TRIANGLES, 0, cnt - 1, (cnt >> 2) * 6, GL_UNSIGNED_INT, 0); }else { - if(!dp.bindQuad16) { - dp.bindQuad16 = true; - dp.bindQuad32 = false; + if(dp.bindQuad != 16) { + dp.bindQuad = 16; attachQuad16EmulationBuffer(true); } - p.drawElements(GL_TRIANGLES, (cnt >> 2) * 6, GL_UNSIGNED_SHORT, 0); + p.drawRangeElements(GL_TRIANGLES, 0, cnt - 1, (cnt >> 2) * 6, GL_UNSIGNED_SHORT, 0); } }else { p.drawArrays(dp.mode, 0, dp.count); @@ -560,6 +578,21 @@ public class EaglercraftGPU { _wglDrawElements(mode, count, type, offset); } + public static void drawRangeElements(int mode, int start, int end, int count, int type, int offset) { + if(emulatedVAOs) { + if(currentVertexArray == null) { + logger.warn("Skipping draw call with emulated VAO because no known VAO is bound!"); + return; + } + ((SoftGLVertexArray)currentVertexArray).transitionToState(emulatedVAOState, true); + } + if(glesVers >= 300) { + _wglDrawRangeElements(mode, start, end, count, type, offset); + }else { + _wglDrawElements(mode, count, type, offset); + } + } + public static void drawArraysInstanced(int mode, int first, int count, int instances) { if(emulatedVAOs) { if(currentVertexArray == null) { @@ -768,7 +801,7 @@ public class EaglercraftGPU { displayListBuffer.put(buffer); lastRender = null; }else { - lastRender = FixedFunctionPipeline.setupDirect(buffer, attrib).update(); + lastRender = FixedFunctionPipeline.setupDirect(buffer, attrib, mode == GL_QUADS).update(); lastRender.drawDirectArrays(mode, 0, count); lastMode = mode; lastCount = count; @@ -845,7 +878,7 @@ public class EaglercraftGPU { v3 = v2 + 1; v4 = v3 + 1; buf.put(v1 | (v2 << 16)); - buf.put(v4 | (v2 << 16)); + buf.put(v3 | (v1 << 16)); buf.put(v3 | (v4 << 16)); } buf.flip(); @@ -862,7 +895,7 @@ public class EaglercraftGPU { v3 = v2 + 1; v4 = v3 + 1; buf.put(v1); buf.put(v2); - buf.put(v4); buf.put(v2); + buf.put(v3); buf.put(v1); buf.put(v3); buf.put(v4); } buf.flip(); @@ -891,7 +924,7 @@ public class EaglercraftGPU { } FixedFunctionPipeline p = FixedFunctionPipeline.setupRenderDisplayList(mesh.getAttribBits()).update(); EaglercraftGPU.bindGLVertexArray(mesh.vertexArray); - p.drawElements(GL_TRIANGLES, mesh.indexCount, GL_UNSIGNED_SHORT, 0); + p.drawRangeElements(GL_TRIANGLES, 0, mesh.vertexCount - 1, mesh.indexCount, GL_UNSIGNED_SHORT, 0); } static int glesVers = -1; diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/FixedFunctionPipeline.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/FixedFunctionPipeline.java index 60c4b64f..2716abae 100755 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/FixedFunctionPipeline.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/FixedFunctionPipeline.java @@ -30,12 +30,9 @@ import net.lax1dude.eaglercraft.v1_8.internal.IVertexArrayGL; 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.internal.PlatformOpenGL; 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; @@ -61,7 +58,7 @@ public class FixedFunctionPipeline { (GlStateManager.stateEnableShaderBlendColor ? STATE_ENABLE_BLEND_ADD : 0); } - static FixedFunctionPipeline setupDirect(ByteBuffer buffer, int attrib) { + static FixedFunctionPipeline setupDirect(ByteBuffer buffer, int attrib, boolean quads) { FixedFunctionPipeline self; int baseState = attrib | getFragmentState(); if(GlStateManager.stateUseExtensionPipeline) { @@ -74,13 +71,13 @@ public class FixedFunctionPipeline { self = getPipelineInstanceCore(baseState); } - StreamBufferInstance sb = self.streamBuffer.getBuffer(buffer.remaining()); - self.currentVertexArray = sb; + EaglercraftGPU.bindGLVertexArray(self.getDirectModeVertexArray()); - EaglercraftGPU.bindGLVertexArray(sb.getVertexArray()); - EaglercraftGPU.bindGLArrayBuffer(sb.getVertexBuffer()); + int off = StreamBuffer.uploadData(self.attribStride, buffer.remaining() / self.attribStride, quads); - _wglBufferSubData(GL_ARRAY_BUFFER, 0, buffer); + _wglBufferSubData(GL_ARRAY_BUFFER, off * self.attribStride, buffer); + + self.directBaseOffset = off; return self; } @@ -132,16 +129,19 @@ public class FixedFunctionPipeline { } static FixedFunctionPipeline setupRenderDisplayList(int attribs) { + FixedFunctionPipeline self; int baseState = attribs | getFragmentState(); if(GlStateManager.stateUseExtensionPipeline) { if(extensionProvider != null) { - return getPipelineInstanceExt(baseState, extensionProvider.getCurrentExtensionStateBits(baseState)); + self = getPipelineInstanceExt(baseState, extensionProvider.getCurrentExtensionStateBits(baseState)); }else { throw new IllegalStateException("No extension pipeline is available!"); } }else { - return getPipelineInstanceCore(baseState); + self = getPipelineInstanceCore(baseState); } + + return self; } void drawArrays(int mode, int offset, int count) { @@ -151,24 +151,26 @@ public class FixedFunctionPipeline { void drawDirectArrays(int mode, int offset, int count) { EaglercraftGPU.bindGLShaderProgram(shaderProgram); + offset += directBaseOffset; if(mode == GL_QUADS) { - StreamBufferInstance sb = currentVertexArray; - if(count > EaglercraftGPU.quad16MaxVertices) { - if(!sb.bindQuad32) { - sb.bindQuad16 = false; - sb.bindQuad32 = true; + int offset2 = (offset >> 2) * 6; + int count2 = (count >> 2) * 6; + if(offset + count > EaglercraftGPU.quad16MaxVertices) { + if(directQuads != 32) { + directQuads = 32; EaglercraftGPU.attachQuad32EmulationBuffer(count, true); }else { EaglercraftGPU.attachQuad32EmulationBuffer(count, false); } - EaglercraftGPU.drawElements(GL_TRIANGLES, (count >> 2) * 6, GL_UNSIGNED_INT, 0); + EaglercraftGPU.drawRangeElements(GL_TRIANGLES, offset, offset + count - 1, count2, GL_UNSIGNED_INT, + offset2 << 2); }else { - if(!sb.bindQuad16) { - sb.bindQuad16 = true; - sb.bindQuad32 = false; + if(directQuads != 16) { + directQuads = 16; EaglercraftGPU.attachQuad16EmulationBuffer(true); } - EaglercraftGPU.drawElements(GL_TRIANGLES, (count >> 2) * 6, GL_UNSIGNED_SHORT, 0); + EaglercraftGPU.drawRangeElements(GL_TRIANGLES, offset, offset + count - 1, count2, GL_UNSIGNED_SHORT, + offset2 << 1); } }else { EaglercraftGPU.drawArrays(mode, offset, count); @@ -180,6 +182,11 @@ public class FixedFunctionPipeline { EaglercraftGPU.drawElements(mode, count, type, offset); } + void drawRangeElements(int mode, int start, int end, int count, int type, int offset) { + EaglercraftGPU.bindGLShaderProgram(shaderProgram); + EaglercraftGPU.drawRangeElements(mode, start, end, count, type, offset); + } + private static IExtPipelineCompiler extensionProvider; public static void loadExtensionPipeline(IExtPipelineCompiler provider) { @@ -423,9 +430,9 @@ public class FixedFunctionPipeline { private float stateAlphaTestRef = -999.0f; private final IUniformGL stateLightsEnabledUniform1i; - private final IUniformGL[] stateLightsVectorsArrayUniform4f = new IUniformGL[4]; + private final IUniformGL[] stateLightsVectorsArrayUniform4f = new IUniformGL[2]; private int stateLightsEnabled = -1; - private final Vector4f[] stateLightsVectors = new Vector4f[4]; + private final Vector4f[] stateLightsVectors = new Vector4f[2]; private int stateLightingSerial = -1; private final IUniformGL stateLightingAmbientUniform3f; @@ -496,8 +503,9 @@ public class FixedFunctionPipeline { private float stateAnisotropicFixH = -999.0f; private float stateAnisotropicFixSerial = 0; - private final StreamBuffer streamBuffer; - private StreamBufferInstance currentVertexArray = null; + private IVertexArrayGL directVertexArray; + private int directBaseOffset; + private byte directQuads; private static FloatBuffer matrixCopyBuffer = null; @@ -572,39 +580,6 @@ public class FixedFunctionPipeline { } throw new IllegalStateException("Program could not be linked!"); } - - streamBuffer = new StreamBuffer((vertexArray, vertexBuffer) -> { - EaglercraftGPU.bindGLVertexArray(vertexArray); - EaglercraftGPU.bindVAOGLArrayBuffer(vertexBuffer); - - EaglercraftGPU.enableVertexAttribArray(0); - EaglercraftGPU.vertexAttribPointer(0, VertexFormat.COMPONENT_POSITION_SIZE, - VertexFormat.COMPONENT_POSITION_FORMAT, false, attribStride, 0); - - if(attribTextureIndex != -1) { - EaglercraftGPU.enableVertexAttribArray(attribTextureIndex); - EaglercraftGPU.vertexAttribPointer(attribTextureIndex, VertexFormat.COMPONENT_TEX_SIZE, - VertexFormat.COMPONENT_TEX_FORMAT, false, attribStride, attribTextureOffset); - } - - if(attribColorIndex != -1) { - EaglercraftGPU.enableVertexAttribArray(attribColorIndex); - EaglercraftGPU.vertexAttribPointer(attribColorIndex, VertexFormat.COMPONENT_COLOR_SIZE, - VertexFormat.COMPONENT_COLOR_FORMAT, true, attribStride, attribColorOffset); - } - - if(attribNormalIndex != -1) { - EaglercraftGPU.enableVertexAttribArray(attribNormalIndex); - EaglercraftGPU.vertexAttribPointer(attribNormalIndex, VertexFormat.COMPONENT_NORMAL_SIZE, - VertexFormat.COMPONENT_NORMAL_FORMAT, true, attribStride, attribNormalOffset); - } - - if(attribLightmapIndex != -1) { - EaglercraftGPU.enableVertexAttribArray(attribLightmapIndex); - EaglercraftGPU.vertexAttribPointer(attribLightmapIndex, VertexFormat.COMPONENT_LIGHTMAP_SIZE, - VertexFormat.COMPONENT_LIGHTMAP_FORMAT, false, attribStride, attribLightmapOffset); - } - }); stateEnableTexture2D = (bits & STATE_ENABLE_TEXTURE2D) != 0; stateEnableLightmap = (bits & STATE_ENABLE_LIGHTMAP) != 0; @@ -899,9 +874,7 @@ public class FixedFunctionPipeline { _wglUniform3f(stateLightingAmbientUniform3f, r, g, b); } } - } - - if(stateEnableMCLighting || DynamicLightsStateManager.isInDynamicLightsPass()) { + if(!stateHasAttribNormal) { serial = GlStateManager.stateNormalSerial; if(stateNormalSerial != serial) { @@ -1089,13 +1062,51 @@ public class FixedFunctionPipeline { } pipelineListTracker.clear(); } - - public void destroy() { - PlatformOpenGL._wglDeleteProgram(shaderProgram); - streamBuffer.destroy(); - } - + public IVertexArrayGL getDirectModeVertexArray() { - return currentVertexArray.vertexArray; + if (directVertexArray == null) { + directVertexArray = EaglercraftGPU.createGLVertexArray(); + EaglercraftGPU.bindGLVertexArray(directVertexArray); + EaglercraftGPU.bindVAOGLArrayBuffer(StreamBuffer.getBuffer()); + + EaglercraftGPU.enableVertexAttribArray(0); + EaglercraftGPU.vertexAttribPointer(0, VertexFormat.COMPONENT_POSITION_SIZE, + VertexFormat.COMPONENT_POSITION_FORMAT, false, attribStride, 0); + + if (attribTextureIndex != -1) { + EaglercraftGPU.enableVertexAttribArray(attribTextureIndex); + EaglercraftGPU.vertexAttribPointer(attribTextureIndex, VertexFormat.COMPONENT_TEX_SIZE, + VertexFormat.COMPONENT_TEX_FORMAT, false, attribStride, attribTextureOffset); + } + + if (attribColorIndex != -1) { + EaglercraftGPU.enableVertexAttribArray(attribColorIndex); + EaglercraftGPU.vertexAttribPointer(attribColorIndex, VertexFormat.COMPONENT_COLOR_SIZE, + VertexFormat.COMPONENT_COLOR_FORMAT, true, attribStride, attribColorOffset); + } + + if (attribNormalIndex != -1) { + EaglercraftGPU.enableVertexAttribArray(attribNormalIndex); + EaglercraftGPU.vertexAttribPointer(attribNormalIndex, VertexFormat.COMPONENT_NORMAL_SIZE, + VertexFormat.COMPONENT_NORMAL_FORMAT, true, attribStride, attribNormalOffset); + } + + if (attribLightmapIndex != -1) { + EaglercraftGPU.enableVertexAttribArray(attribLightmapIndex); + EaglercraftGPU.vertexAttribPointer(attribLightmapIndex, VertexFormat.COMPONENT_LIGHTMAP_SIZE, + VertexFormat.COMPONENT_LIGHTMAP_FORMAT, false, attribStride, attribLightmapOffset); + } + + return directVertexArray; + } + return directVertexArray; } + + public void destroy() { + _wglDeleteProgram(shaderProgram); + if (directVertexArray != null) { + EaglercraftGPU.destroyGLVertexArray(directVertexArray); + } + } + } \ No newline at end of file diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/FixedFunctionShader.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/FixedFunctionShader.java index f085c242..15e93987 100755 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/FixedFunctionShader.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/FixedFunctionShader.java @@ -44,7 +44,7 @@ public class FixedFunctionShader { public static final String FILENAME_VSH = "/assets/eagler/glsl/core.vsh"; public static final String FILENAME_FSH = "/assets/eagler/glsl/core.fsh"; - public static final String PRECISION_INT = "lowp"; + public static final String PRECISION_INT = "mediump"; public static final String PRECISION_FLOAT = "highp"; public static final String PRECISION_SAMPLER = "mediump"; diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/GlStateManager.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/GlStateManager.java index 5d3acadd..7ba5a8ef 100755 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/GlStateManager.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/GlStateManager.java @@ -76,9 +76,9 @@ public class GlStateManager { static boolean stateMaterial = false; static boolean stateLighting = false; static int stateLightsStackPointer = 0; - static final boolean[][] stateLightsEnabled = new boolean[4][8]; - static final Vector4f[][] stateLightsStack = new Vector4f[4][8]; - static final int[] stateLightingSerial = new int[4]; + static final boolean[][] stateLightsEnabled = new boolean[2][8]; + static final Vector4f[][] stateLightsStack = new Vector4f[2][8]; + static final int[] stateLightingSerial = new int[2]; static float stateLightingAmbientR = 0.0f; static float stateLightingAmbientG = 0.0f; diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/InstancedFontRenderer.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/InstancedFontRenderer.java index 420dcb34..15fd8ff3 100755 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/InstancedFontRenderer.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/InstancedFontRenderer.java @@ -206,8 +206,7 @@ public class InstancedFontRenderer { EaglercraftGPU.vertexAttribPointer(0, 3, GL_FLOAT, false, 12, 0); EaglercraftGPU.vertexAttribDivisor(0, 0); - EaglercraftGPU.bindVAOGLArrayBufferNow(instancesBuffer); - _wglBufferData(GL_ARRAY_BUFFER, fontDataBuffer.capacity(), GL_STREAM_DRAW); + EaglercraftGPU.bindVAOGLArrayBuffer(instancesBuffer); EaglercraftGPU.enableVertexAttribArray(1); EaglercraftGPU.vertexAttribPointer(1, 2, GL_SHORT, false, 10, 0); @@ -381,7 +380,7 @@ public class InstancedFontRenderer { int l = fontDataBuffer.limit(); fontDataBuffer.flip(); - _wglBufferData(GL_ARRAY_BUFFER, fontDataBuffer.capacity(), GL_STREAM_DRAW); + _wglBufferData(GL_ARRAY_BUFFER, (fontDataBuffer.remaining() + 0x3FF) & 0xFFFFFC00, GL_STREAM_DRAW); _wglBufferSubData(GL_ARRAY_BUFFER, 0, fontDataBuffer); fontDataBuffer.position(p); @@ -395,7 +394,7 @@ public class InstancedFontRenderer { int l = fontBoldDataBuffer.limit(); fontBoldDataBuffer.flip(); - _wglBufferData(GL_ARRAY_BUFFER, fontBoldDataBuffer.capacity(), GL_STREAM_DRAW); + _wglBufferData(GL_ARRAY_BUFFER, (fontBoldDataBuffer.remaining() + 0x3FF) & 0xFFFFFC00, GL_STREAM_DRAW); _wglBufferSubData(GL_ARRAY_BUFFER, 0, fontBoldDataBuffer); fontBoldDataBuffer.position(p); diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/InstancedParticleRenderer.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/InstancedParticleRenderer.java index 4f5fd333..a10b134d 100755 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/InstancedParticleRenderer.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/InstancedParticleRenderer.java @@ -187,8 +187,7 @@ public class InstancedParticleRenderer { EaglercraftGPU.vertexAttribPointer(0, 2, GL_FLOAT, false, 8, 0); EaglercraftGPU.vertexAttribDivisor(0, 0); - EaglercraftGPU.bindVAOGLArrayBufferNow(instancesBuffer); - _wglBufferData(GL_ARRAY_BUFFER, particleBuffer.capacity(), GL_STREAM_DRAW); + EaglercraftGPU.bindVAOGLArrayBuffer(instancesBuffer); EaglercraftGPU.enableVertexAttribArray(1); EaglercraftGPU.vertexAttribPointer(1, 3, GL_FLOAT, false, 24, 0); @@ -315,7 +314,7 @@ public class InstancedParticleRenderer { int l = particleBuffer.limit(); particleBuffer.flip(); - _wglBufferData(GL_ARRAY_BUFFER, particleBuffer.capacity(), GL_STREAM_DRAW); + _wglBufferData(GL_ARRAY_BUFFER, (particleBuffer.remaining() + 0xFFF) & 0xFFFFF000, GL_STREAM_DRAW); _wglBufferSubData(GL_ARRAY_BUFFER, 0, particleBuffer); particleBuffer.position(p); diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/StreamBuffer.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/StreamBuffer.java index 8d89c28c..63311189 100755 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/StreamBuffer.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/StreamBuffer.java @@ -16,108 +16,53 @@ package net.lax1dude.eaglercraft.v1_8.opengl; -import net.lax1dude.eaglercraft.v1_8.internal.IVertexArrayGL; import net.lax1dude.eaglercraft.v1_8.internal.IBufferGL; import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*; import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*; +/** + * This streaming implementation was designed by reverse engineering the OpenGL + * driver that powers most Intel-based Chromebooks, performance may vary on + * other platforms + */ public class StreamBuffer { - public static final int poolSize = 4; + protected static IBufferGL buffer = null; - protected static final PoolInstance[] pool = new PoolInstance[poolSize]; - protected static int poolBufferID = 0; + protected static int currentOffset = 0; + protected static int currentSize = 0; - static { - for(int i = 0; i < poolSize; ++i) { - pool[i] = new PoolInstance(); - } - } - - protected static class PoolInstance { - - protected IBufferGL vertexBuffer = null; - protected int vertexBufferSize = 0; - - } - - private static void resizeInstance(PoolInstance instance, int requiredMemory) { - IBufferGL buffer = instance.vertexBuffer; + public static IBufferGL getBuffer() { if (buffer == null) { - buffer = _wglGenBuffers(); - instance.vertexBuffer = buffer; + return buffer = _wglGenBuffers(); } - int newSize = instance.vertexBufferSize; - if (newSize < requiredMemory) { - newSize = (requiredMemory + 0xFFFF) & 0xFFFF0000; - instance.vertexBufferSize = newSize; - } - EaglercraftGPU.bindGLArrayBuffer(buffer); - _wglBufferData(GL_ARRAY_BUFFER, newSize, GL_STREAM_DRAW); + return buffer; } - protected StreamBufferInstance[] buffers; - - protected final IStreamBufferInitializer initializer; - - public static class StreamBufferInstance { - - protected PoolInstance poolInstance = null; - protected IVertexArrayGL vertexArray = null; - - public boolean bindQuad16 = false; - public boolean bindQuad32 = false; - - public IVertexArrayGL getVertexArray() { - return vertexArray; + public static int uploadData(int elSize, int elCount, boolean quads) { + EaglercraftGPU.bindGLArrayBuffer(getBuffer()); + int off = (currentOffset + elSize - 1) / elSize; + if (quads) { + off = (off + 3) & -4; } - - public IBufferGL getVertexBuffer() { - return poolInstance.vertexBuffer; - } - - } - - public static interface IStreamBufferInitializer { - void initialize(IVertexArrayGL vertexArray, IBufferGL vertexBuffer); - } - - public StreamBuffer(IStreamBufferInitializer initializer) { - this.buffers = new StreamBufferInstance[poolSize]; - for(int i = 0; i < this.buffers.length; ++i) { - StreamBufferInstance j = new StreamBufferInstance(); - j.poolInstance = pool[i]; - this.buffers[i] = j; - } - this.initializer = initializer; - } - - public StreamBufferInstance getBuffer(int requiredMemory) { - StreamBufferInstance next = buffers[poolBufferID++ % buffers.length]; - resizeInstance(next.poolInstance, requiredMemory); - if(next.vertexArray == null) { - next.vertexArray = EaglercraftGPU.createGLVertexArray(); - initializer.initialize(next.vertexArray, next.poolInstance.vertexBuffer); - } - return next; - } - - public void destroy() { - for(int i = 0; i < buffers.length; ++i) { - StreamBufferInstance next = buffers[i]; - if(next.vertexArray != null) { - EaglercraftGPU.destroyGLVertexArray(next.vertexArray); - } + int offBytes = off * elSize; + int reqBytes = elCount * elSize; + if (currentSize - offBytes >= reqBytes) { + currentOffset = offBytes + reqBytes; + return off; + } else { + currentOffset = 0; + currentSize = (reqBytes + 0xFFFF) & 0xFFFFF000; + _wglBufferData(GL_ARRAY_BUFFER, currentSize, GL_STREAM_DRAW); + return 0; } } public static void destroyPool() { - for(int i = 0; i < pool.length; ++i) { - if(pool[i].vertexBuffer != null) { - _wglDeleteBuffers(pool[i].vertexBuffer); - pool[i].vertexBuffer = null; - } + if (buffer != null) { + _wglDeleteBuffers(buffer); + buffer = null; } } diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/deferred/LensFlareMeshRenderer.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/deferred/LensFlareMeshRenderer.java index f9c5cffc..c1b91293 100755 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/deferred/LensFlareMeshRenderer.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/deferred/LensFlareMeshRenderer.java @@ -316,7 +316,8 @@ public class LensFlareMeshRenderer { _wglUniform3f(streaksProgram.uniforms.u_flareColor3f, v.x * mag * 0.5f, v.y * mag * 0.5f, v.z * mag * 0.5f); EaglercraftGPU.bindGLVertexArray(streaksVertexArray); - _wglDrawElements(GL_TRIANGLES, streaksVertexCount + (streaksVertexCount >> 1), GL_UNSIGNED_SHORT, 0); + _wglDrawRangeElements(GL_TRIANGLES, 0, streaksVertexCount - 1, streaksVertexCount + (streaksVertexCount >> 1), + GL_UNSIGNED_SHORT, 0); ghostsProgram.useProgram(); diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/dynamiclights/DynamicLightBucketLoader.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/dynamiclights/DynamicLightBucketLoader.java index d21cb265..417ccdea 100755 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/dynamiclights/DynamicLightBucketLoader.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/dynamiclights/DynamicLightBucketLoader.java @@ -46,8 +46,8 @@ public class DynamicLightBucketLoader { private int currentLightSourceBucketId = -1; private int lightingBufferSliceLength = -1; - public static final int MAX_LIGHTS_PER_CHUNK = 12; - public static final int LIGHTING_BUFFER_LENGTH = 16 * MAX_LIGHTS_PER_CHUNK + 16; + public static final int MAX_LIGHTS_PER_CHUNK = 8; + public static final int LIGHTING_BUFFER_LENGTH = 8 * MAX_LIGHTS_PER_CHUNK + 16; private final int lightSourceBucketsWidth; private final int lightSourceBucketsHeight; @@ -114,26 +114,36 @@ public class DynamicLightBucketLoader { int ser = currentLightSourceBucket.getEaglerSerial(); int max = currentLightSourceBucket.size(); if(max > 0) { + if(max > MAX_LIGHTS_PER_CHUNK) { + max = MAX_LIGHTS_PER_CHUNK; + } EaglercraftGPU.bindGLUniformBuffer(buffer_chunkLightingData); int offset = currentLightSourceBucketId * lightingBufferSliceLength; if (lightSourceBucketsSerials[currentLightSourceBucketId] != ser || lightSourceRenderPosSerials[currentLightSourceBucketId] != currentRenderPosSerial) { lightSourceBucketsSerials[currentLightSourceBucketId] = ser; lightSourceRenderPosSerials[currentLightSourceBucketId] = currentRenderPosSerial; - if(max > MAX_LIGHTS_PER_CHUNK) { - max = MAX_LIGHTS_PER_CHUNK; - } + int bucketXOff = -relativeBlockX & -16; + int bucketYOff = -relativeBlockY & -16; + int bucketZOff = -relativeBlockZ & -16; chunkLightingDataCopyBuffer.clear(); + chunkLightingDataCopyBuffer.putInt( + ((bucketXOff & 0xFF) << 8) | + ((bucketYOff & 0xFF) << 16) | + ((bucketZOff & 0xFF) << 24) + ); chunkLightingDataCopyBuffer.putInt(max); - chunkLightingDataCopyBuffer.putInt(0); //padding - chunkLightingDataCopyBuffer.putInt(0); //padding - chunkLightingDataCopyBuffer.putInt(0); //padding + chunkLightingDataCopyBuffer.putInt(0); // padding + chunkLightingDataCopyBuffer.putInt(0); // padding for(int i = 0; i < max; ++i) { DynamicLightInstance dl = currentLightSourceBucket.get(i); - chunkLightingDataCopyBuffer.putFloat((float)(dl.posX - currentRenderX)); - chunkLightingDataCopyBuffer.putFloat((float)(dl.posY - currentRenderY)); - chunkLightingDataCopyBuffer.putFloat((float)(dl.posZ - currentRenderZ)); - chunkLightingDataCopyBuffer.putFloat(dl.radius); + int x = (int)((dl.posX - currentRenderX + bucketXOff) * (1.0f / 0.0009765923f)); + int y = (int)((dl.posY - currentRenderY + bucketYOff) * (1.0f / 0.0009765923f)); + int z = (int)((dl.posZ - currentRenderZ + bucketZOff) * (1.0f / 0.0009765923f)); + int r = (int)(dl.radius * (1.0f / 0.0009765923f)); + if (r > 32767) r = 32767; + chunkLightingDataCopyBuffer.putInt((x & 0xFFFF) | (z << 16)); + chunkLightingDataCopyBuffer.putInt((y & 0xFFFF) | (r << 16)); } chunkLightingDataCopyBuffer.flip(); _wglBufferSubData(_GL_UNIFORM_BUFFER, offset, chunkLightingDataCopyBuffer); diff --git a/src/platform-api/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformOpenGL.java b/src/platform-api/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformOpenGL.java index ec5592ed..b8c84023 100755 --- a/src/platform-api/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformOpenGL.java +++ b/src/platform-api/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformOpenGL.java @@ -204,6 +204,8 @@ public class PlatformOpenGL { public static native void _wglDrawElements(int mode, int count, int type, int offset); + public static native void _wglDrawRangeElements(int mode, int start, int end, int count, int type, int offset); + public static native void _wglDrawArraysInstanced(int mode, int first, int count, int instanced); public static native void _wglDrawElementsInstanced(int mode, int count, int type, int offset, int instanced); diff --git a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformAudio.java b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformAudio.java index 9c245eb6..e82ea6dd 100755 --- a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformAudio.java +++ b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformAudio.java @@ -63,6 +63,7 @@ public class PlatformAudio { static AudioBufferSourceNode recDestSilenceNode = null; static GainNode micRecGain = null; static GainNode gameRecGain = null; + static HTMLAudioElement silenceElement = null; private static final Map soundCache = new HashMap<>(); private static final List activeSounds = new LinkedList<>(); @@ -253,16 +254,33 @@ public class PlatformAudio { HTMLAudioElement audio = (HTMLAudioElement) PlatformRuntime.doc.createElement("audio"); audio.getClassList().add("_eaglercraftX_keepalive_hack"); audio.setAttribute("style", "display:none;"); - audio.setAutoplay(true); + audio.setAutoplay(false); audio.setLoop(true); + audio.addEventListener("seeked", (e) -> { + // NOP, wakes up the browser's event loop + }); + audio.addEventListener("canplay", (e) -> { + if (PlatformRuntime.doc != null && silenceElement != null && + !PlatformInput.getVisibilityState(PlatformRuntime.doc)) { + silenceElement.play(); + } + }); HTMLSourceElement source = (HTMLSourceElement) PlatformRuntime.doc.createElement("source"); source.setType("audio/wav"); source.setSrc(TeaVMBlobURLManager.registerNewURLByte(silenceFile, "audio/wav").toExternalForm()); audio.appendChild(source); - audio.addEventListener("seeked", (e) -> { - // NOP, wakes up the browser's event loop - }); PlatformRuntime.parent.appendChild(audio); + silenceElement = audio; + } + } + } + + static void handleVisibilityChange() { + if (silenceElement != null) { + if (!PlatformInput.getVisibilityState(PlatformRuntime.doc)) { + silenceElement.play(); + } else { + silenceElement.pause(); } } } @@ -607,6 +625,11 @@ public class PlatformAudio { micRecGain = null; gameRecGain = null; } + if(silenceElement != null) { + silenceElement.pause(); + silenceElement.delete(); + silenceElement = null; + } } } \ No newline at end of file diff --git a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformInput.java b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformInput.java index 42c68117..d55035ba 100755 --- a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformInput.java +++ b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformInput.java @@ -103,6 +103,7 @@ public class PlatformInput { private static EventListener pointerlock = null; private static EventListener pointerlockerr = null; private static EventListener fullscreen = null; + private static EventListener visibilitychange = null; private static Map keyCodeTranslatorMap = null; @@ -636,6 +637,12 @@ public class PlatformInput { isWindowFocused = true; } }); + win.getDocument().addEventListener("visibilitychange", visibilitychange = new EventListener() { + @Override + public void handleEvent(Event evt) { + PlatformAudio.handleVisibilityChange(); + } + }); try { pointerLockSupported = getSupportedPointerLock(win.getDocument()); @@ -865,7 +872,7 @@ public class PlatformInput { } @JSBody(params = { "doc" }, script = "return (typeof doc.visibilityState !== \"string\") || (doc.visibilityState === \"visible\");") - private static native boolean getVisibilityState(JSObject doc); + static native boolean getVisibilityState(JSObject doc); @JSBody(params = { "win" }, script = "return (typeof win.devicePixelRatio === \"number\") ? win.devicePixelRatio : 1.0;") static native double getDevicePixelRatio(Window win); @@ -1513,6 +1520,10 @@ public class PlatformInput { win.removeEventListener("blur", blur); blur = null; } + if(visibilitychange != null) { + win.getDocument().removeEventListener("visibilitychange", blur); + visibilitychange = null; + } if(wheel != null) { canvas.removeEventListener("wheel", wheel); wheel = null; diff --git a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformOpenGL.java b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformOpenGL.java index 0cdc9e82..ce24c120 100755 --- a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformOpenGL.java +++ b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformOpenGL.java @@ -600,6 +600,11 @@ public class PlatformOpenGL { //checkErr("_wglDrawElements(" + mode + ", " + count + ", " + type + ", " + offset + ");"); } + public static void _wglDrawRangeElements(int mode, int start, int end, int count, int type, int offset) { + ctx.drawRangeElements(mode, start, end, count, type, offset); + //checkErr("_wglDrawRangeElements(" + mode + ", " + start + ", " + end + ", " + count + ", " + type + ", " + offset + ");"); + } + public static void _wglDrawElementsInstanced(int mode, int count, int type, int offset, int instances) { switch(instancingImpl) { case INSTANCE_IMPL_CORE: diff --git a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/teavm/WebGL2RenderingContext.java b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/teavm/WebGL2RenderingContext.java index aed57b8a..f93e3479 100755 --- a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/teavm/WebGL2RenderingContext.java +++ b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/teavm/WebGL2RenderingContext.java @@ -72,6 +72,8 @@ public interface WebGL2RenderingContext extends WebGLRenderingContext { void drawElementsInstanced(int p1, int p2, int p3, int p4, int p5); + void drawRangeElements(int p1, int p2, int p3, int p4, int p5, int p6); + int getUniformBlockIndex(WebGLProgram p1, String p2); void bindBufferRange(int p1, int p2, WebGLBuffer p3, int p4, int p5); diff --git a/src/wasm-gc-teavm-loader/c/main.c b/src/wasm-gc-teavm-loader/c/main.c index 8a42e8aa..2129ab10 100755 --- a/src/wasm-gc-teavm-loader/c/main.c +++ b/src/wasm-gc-teavm-loader/c/main.c @@ -26,6 +26,7 @@ static uint32_t initEPWBinaryCompressedHelper(struct epw_slice_compressed* slice static uint32_t initEPWBinaryHelper(struct epw_slice* sliceIn, uint32_t epwLen); static uint32_t initEPWStringHelper(struct epw_slice* sliceIn, uint32_t epwLen); +#define SLICE_IS_PRESENT(pSlice) (((struct epw_slice_compressed*)(pSlice))->sliceCompressedLength && ((struct epw_slice_compressed*)(pSlice))->sliceDecompressedLength) #define SLICE_IN_BOUNDS(pSlice, epwLen) (((struct epw_slice*)(pSlice))->sliceOffset + ((struct epw_slice*)(pSlice))->sliceLength <= (epwLen)) // Note: Linux kernel uses 4096 @@ -186,20 +187,28 @@ int main(int argc, char** argv) { return -1; } - dbgLog("Decompressing classes.wasm.teadbg..."); - - result->classesDeobfTEADBGData = initEPWBinaryCompressedHelper(&headerPtr->classesDeobfTEADBGData, epwLen); - if(!result->classesDeobfTEADBGData) { - resultFailed(EPW_INVALID); - return -1; + if(SLICE_IS_PRESENT(&headerPtr->classesDeobfTEADBGData)) { + dbgLog("Decompressing classes.wasm.teadbg..."); + + result->classesDeobfTEADBGData = initEPWBinaryCompressedHelper(&headerPtr->classesDeobfTEADBGData, epwLen); + if(!result->classesDeobfTEADBGData) { + resultFailed(EPW_INVALID); + return -1; + } + }else { + result->classesDeobfTEADBGData = -1; } - dbgLog("Decompressing deobfuscator..."); - - result->classesDeobfWASMData = initEPWBinaryCompressedHelper(&headerPtr->classesDeobfWASMData, epwLen); - if(!result->classesDeobfWASMData) { - resultFailed(EPW_INVALID); - return -1; + if(SLICE_IS_PRESENT(&headerPtr->classesDeobfWASMData)) { + dbgLog("Decompressing deobfuscator..."); + + result->classesDeobfWASMData = initEPWBinaryCompressedHelper(&headerPtr->classesDeobfWASMData, epwLen); + if(!result->classesDeobfWASMData) { + resultFailed(EPW_INVALID); + return -1; + } + }else { + result->classesDeobfWASMData = -1; } result->numEPKs = numEPKs; diff --git a/src/wasm-gc-teavm-loader/js/library.js b/src/wasm-gc-teavm-loader/js/library.js index b0266094..0a2ec02a 100755 --- a/src/wasm-gc-teavm-loader/js/library.js +++ b/src/wasm-gc-teavm-loader/js/library.js @@ -78,8 +78,8 @@ addToLibrary({ const eagRuntimeJSURL = URL.createObjectURL(new Blob([results[HEAP32[idx]]], { type: "text/javascript;charset=utf-8" })); const classesWASMURL = URL.createObjectURL(new Blob([results[HEAP32[idx + 1]]], { type: "application/wasm" })); - const classesDeobfTEADBGURL = URL.createObjectURL(new Blob([results[HEAP32[idx + 2]]], { type: "application/octet-stream" })); - const classesDeobfWASMURL = URL.createObjectURL(new Blob([results[HEAP32[idx + 3]]], { type: "application/wasm" })); + const classesDeobfTEADBGURL = HEAP32[idx + 2] !== -1 ? URL.createObjectURL(new Blob([results[HEAP32[idx + 2]]], { type: "application/octet-stream" })) : null; + const classesDeobfWASMURL = HEAP32[idx + 3] !== -1 ? URL.createObjectURL(new Blob([results[HEAP32[idx + 3]]], { type: "application/wasm" })) : null; const pressAnyKey = URL.createObjectURL(new Blob([results[HEAP32[idx + 4]]], { type: results[HEAP32[idx + 5]] })); const crashImg = URL.createObjectURL(new Blob([results[HEAP32[idx + 6]]], { type: results[HEAP32[idx + 7]] })); diff --git a/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformAudio.java b/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformAudio.java index fd5e7016..4841af11 100755 --- a/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformAudio.java +++ b/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformAudio.java @@ -22,6 +22,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import org.teavm.interop.Address; import org.teavm.interop.Import; import org.teavm.jso.JSBody; import org.teavm.jso.JSObject; @@ -41,6 +42,7 @@ import org.teavm.jso.webaudio.PannerNode; import net.lax1dude.eaglercraft.v1_8.EagRuntime; import net.lax1dude.eaglercraft.v1_8.internal.buffer.MemoryStack; import net.lax1dude.eaglercraft.v1_8.internal.buffer.WASMGCDirectArrayConverter; +import net.lax1dude.eaglercraft.v1_8.internal.buffer.WASMGCDirectArrayCopy; import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.BetterJSStringConverter; import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.JOrbisAudioBufferDecoder; import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.WASMGCClientConfigAdapter; @@ -100,7 +102,10 @@ public class PlatformAudio { if (silenceFile != null) { MemoryStack.push(); try { - initKeepAliveHack(WASMGCDirectArrayConverter.byteArrayToStackU8Array(silenceFile)); + int len = silenceFile.length; + Address addr = MemoryStack.malloc(len); + WASMGCDirectArrayCopy.memcpy(addr, silenceFile, 0, len); + initKeepAliveHack(addr, len); }finally { MemoryStack.pop(); } @@ -112,7 +117,7 @@ public class PlatformAudio { private static native AudioContext getContext(); @Import(module = "platformAudio", name = "initKeepAliveHack") - private static native void initKeepAliveHack(Uint8Array array); + private static native void initKeepAliveHack(Address addr, int length); protected static class BrowserAudioResource implements IAudioResource { diff --git a/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformOpenGL.java b/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformOpenGL.java index 73449e2f..d4db127f 100755 --- a/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformOpenGL.java +++ b/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformOpenGL.java @@ -199,7 +199,7 @@ public class PlatformOpenGL { @Import(module = "platformOpenGL", name = "glReadPixels") static native void _wglReadPixelsN(int x, int y, int width, int height, int format, int type, ArrayBufferView array); - @Import(module = "platformOpenGL", name = "glReadPixels0") + @Import(module = "platformOpenGL", name = "glReadPixels") static native void _wglReadPixelsN(int x, int y, int width, int height, int format, int type, ArrayBufferView array, int offset); @Import(module = "platformOpenGL", name = "glPolygonOffset") @@ -367,7 +367,7 @@ public class PlatformOpenGL { @Import(module = "platformOpenGL", name = "glBufferData") static native void _wglBufferDataN(int target, ArrayBufferView typedArray, int usage); - @Import(module = "platformOpenGL", name = "glBufferData0") + @Import(module = "platformOpenGL", name = "glBufferData") static native void _wglBufferDataN(int target, ArrayBufferView typedArray, int usage, int srcOffset, int length); public static void _wglBufferSubData(int target, int dstOffset, ByteBuffer buffer) { @@ -397,7 +397,7 @@ public class PlatformOpenGL { @Import(module = "platformOpenGL", name = "glBufferSubData") static native void _wglBufferSubDataN(int target, int dstOffset, ArrayBufferView typedArray); - @Import(module = "platformOpenGL", name = "glBufferSubData0") + @Import(module = "platformOpenGL", name = "glBufferSubData") static native void _wglBufferSubDataN(int target, int dstOffset, ArrayBufferView typedArray, int srcOffset, int length); public static void _wglBindVertexArray(IVertexArrayGL objId) { @@ -450,7 +450,7 @@ public class PlatformOpenGL { static native void _wglTexImage3DN(int target, int level, int internalFormat, int width, int height, int depth, int border, int format, int type, ArrayBufferView typedArray); - @Import(module = "platformOpenGL", name = "glTexImage3D0") + @Import(module = "platformOpenGL", name = "glTexImage3D") static native void _wglTexImage3DN(int target, int level, int internalFormat, int width, int height, int depth, int border, int format, int type, ArrayBufferView typedArray, int offset); @@ -513,7 +513,7 @@ public class PlatformOpenGL { static native void _wglTexImage2DN(int target, int level, int internalFormat, int width, int height, int border, int format, int type, ArrayBufferView typedArray); - @Import(module = "platformOpenGL", name = "glTexImage2D0") + @Import(module = "platformOpenGL", name = "glTexImage2D") static native void _wglTexImage2DN(int target, int level, int internalFormat, int width, int height, int border, int format, int type, ArrayBufferView typedArray, int offset); @@ -565,7 +565,7 @@ public class PlatformOpenGL { static native void _wglTexSubImage2D(int target, int level, int offsetx, int offsety, int width, int height, int format, int type, ArrayBufferView typedArray); - @Import(module = "platformOpenGL", name = "glTexSubImage2D0") + @Import(module = "platformOpenGL", name = "glTexSubImage2D") static native void _wglTexSubImage2D(int target, int level, int offsetx, int offsety, int width, int height, int format, int type, ArrayBufferView typedArray, int offset); @@ -658,6 +658,9 @@ public class PlatformOpenGL { @Import(module = "platformOpenGL", name = "glDrawElements") public static native void _wglDrawElements(int mode, int count, int type, int offset); + @Import(module = "platformOpenGL", name = "glDrawRangeElements") + public static native void _wglDrawRangeElements(int mode, int start, int end, int count, int type, int offset); + @Import(module = "platformOpenGL", name = "glDrawArraysInstanced") public static native void _wglDrawArraysInstanced(int mode, int first, int count, int instanced); diff --git a/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformWebView.java b/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformWebView.java index 5b9cf740..a7295221 100755 --- a/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformWebView.java +++ b/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformWebView.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.LinkedList; import java.util.List; +import org.teavm.interop.Address; import org.teavm.interop.Import; import org.teavm.jso.JSBody; import org.teavm.jso.JSObject; @@ -32,6 +33,7 @@ import org.teavm.jso.typedarrays.Uint8Array; import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime.JSEagRuntimeEvent; import net.lax1dude.eaglercraft.v1_8.internal.buffer.MemoryStack; import net.lax1dude.eaglercraft.v1_8.internal.buffer.WASMGCDirectArrayConverter; +import net.lax1dude.eaglercraft.v1_8.internal.buffer.WASMGCDirectArrayCopy; import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.BetterJSStringConverter; import net.lax1dude.eaglercraft.v1_8.log4j.LogManager; import net.lax1dude.eaglercraft.v1_8.log4j.Logger; @@ -226,8 +228,10 @@ public class PlatformWebView { }else if(packet.type == SPacketWebViewMessageV4EAG.TYPE_BINARY) { MemoryStack.push(); try { - sendBinaryMessage(BetterJSStringConverter.stringToJS(currentMessageChannelName), - WASMGCDirectArrayConverter.byteArrayToStackU8Array(packet.data)); + int len = packet.data.length; + Address addr = MemoryStack.malloc(len); + WASMGCDirectArrayCopy.memcpy(addr, packet.data, 0, len); + sendBinaryMessage(BetterJSStringConverter.stringToJS(currentMessageChannelName), addr, len); }finally { MemoryStack.pop(); } @@ -241,7 +245,7 @@ public class PlatformWebView { private static native void sendStringMessage(JSString ch, JSString str); @Import(module = "platformWebView", name = "sendBinaryMessage") - private static native void sendBinaryMessage(JSString ch, Uint8Array bin); + private static native void sendBinaryMessage(JSString ch, Address addr, int length); private static void sendMessageToServer(String channelName, int type, byte[] data) { if(channelName.length() > 255) { diff --git a/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/internal/wasm_gc_teavm/IndexedDBFilesystem.java b/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/internal/wasm_gc_teavm/IndexedDBFilesystem.java index b0d7ba89..1c6cf684 100755 --- a/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/internal/wasm_gc_teavm/IndexedDBFilesystem.java +++ b/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/internal/wasm_gc_teavm/IndexedDBFilesystem.java @@ -16,6 +16,7 @@ package net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm; +import org.teavm.interop.Address; import org.teavm.interop.Import; import org.teavm.jso.JSObject; import org.teavm.jso.JSProperty; @@ -124,16 +125,14 @@ public class IndexedDBFilesystem implements IEaglerFilesystem { @Override public void eaglerWrite(String pathName, ByteBuffer data) { - int len = data.remaining(); - Uint8Array arr = new Uint8Array(len); - arr.set(WASMGCBufferAllocator.getByteBufferView(data)); - if(!eaglerWrite(database, BetterJSStringConverter.stringToJS(pathName), arr.getBuffer())) { - throw new EaglerFileSystemException("Failed to write " + len + " byte file to indexeddb table: " + pathName); + if(!eaglerWrite(database, BetterJSStringConverter.stringToJS(pathName), + WASMGCBufferAllocator.getByteBufferAddress(data), data.remaining())) { + throw new EaglerFileSystemException("Failed to write " + data.remaining() + " byte file to indexeddb table: " + pathName); } } @Import(module = "platformFilesystem", name = "eaglerWrite") - private static native boolean eaglerWrite(IDBDatabase database, JSString pathName, ArrayBuffer arr); + private static native boolean eaglerWrite(IDBDatabase database, JSString pathName, Address addr, int length); @Override public boolean eaglerExists(String pathName) { diff --git a/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/internal/wasm_gc_teavm/WASMGCWebSocketClient.java b/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/internal/wasm_gc_teavm/WASMGCWebSocketClient.java index 0ed0b2e2..6e9834b9 100755 --- a/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/internal/wasm_gc_teavm/WASMGCWebSocketClient.java +++ b/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/internal/wasm_gc_teavm/WASMGCWebSocketClient.java @@ -21,7 +21,6 @@ import java.util.List; import org.teavm.jso.JSObject; import org.teavm.jso.JSProperty; -import org.teavm.jso.core.JSString; import org.teavm.jso.typedarrays.Uint8Array; import net.lax1dude.eaglercraft.v1_8.EagUtils; diff --git a/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/sp/internal/ClientPlatformSingleplayer.java b/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/sp/internal/ClientPlatformSingleplayer.java index 151b208d..ef127644 100755 --- a/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/sp/internal/ClientPlatformSingleplayer.java +++ b/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/sp/internal/ClientPlatformSingleplayer.java @@ -21,14 +21,14 @@ import java.util.Arrays; import java.util.LinkedList; import java.util.List; +import org.teavm.interop.Address; import org.teavm.interop.Import; import org.teavm.jso.core.JSString; -import org.teavm.jso.typedarrays.Uint8Array; import net.lax1dude.eaglercraft.v1_8.internal.IPCPacketData; import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime; import net.lax1dude.eaglercraft.v1_8.internal.buffer.MemoryStack; -import net.lax1dude.eaglercraft.v1_8.internal.buffer.WASMGCDirectArrayConverter; +import net.lax1dude.eaglercraft.v1_8.internal.buffer.WASMGCDirectArrayCopy; import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.BetterJSStringConverter; import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.WASMGCClientConfigAdapter; import net.lax1dude.eaglercraft.v1_8.log4j.LogManager; @@ -71,8 +71,10 @@ public class ClientPlatformSingleplayer { }else { MemoryStack.push(); try { - sendPacket0(BetterJSStringConverter.stringToJS(packet.channel), - WASMGCDirectArrayConverter.byteArrayToStackU8Array(packet.contents)); + int len = packet.contents.length; + Address addr = MemoryStack.malloc(len); + WASMGCDirectArrayCopy.memcpy(addr, packet.contents, 0, len); + sendPacket0(BetterJSStringConverter.stringToJS(packet.channel), addr, len); } finally { MemoryStack.pop(); } @@ -80,7 +82,7 @@ public class ClientPlatformSingleplayer { } @Import(module = "clientPlatformSingleplayer", name = "sendPacket") - private static native void sendPacket0(JSString channel, Uint8Array arr); + private static native void sendPacket0(JSString channel, Address addr, int length); public static List recieveAllPacket() { if(isSingleThreadMode) { diff --git a/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/sp/server/internal/ServerPlatformSingleplayer.java b/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/sp/server/internal/ServerPlatformSingleplayer.java index 40b5b7df..cc5dd780 100755 --- a/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/sp/server/internal/ServerPlatformSingleplayer.java +++ b/src/wasm-gc-teavm/java/net/lax1dude/eaglercraft/v1_8/sp/server/internal/ServerPlatformSingleplayer.java @@ -22,11 +22,11 @@ import java.util.LinkedList; import java.util.List; import java.util.function.Consumer; +import org.teavm.interop.Address; import org.teavm.interop.Import; import org.teavm.jso.JSFunctor; import org.teavm.jso.JSObject; import org.teavm.jso.core.JSString; -import org.teavm.jso.typedarrays.Uint8Array; import net.lax1dude.eaglercraft.v1_8.Filesystem; import net.lax1dude.eaglercraft.v1_8.internal.IClientConfigAdapter; @@ -34,7 +34,7 @@ import net.lax1dude.eaglercraft.v1_8.internal.IEaglerFilesystem; import net.lax1dude.eaglercraft.v1_8.internal.IPCPacketData; import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime; import net.lax1dude.eaglercraft.v1_8.internal.buffer.MemoryStack; -import net.lax1dude.eaglercraft.v1_8.internal.buffer.WASMGCDirectArrayConverter; +import net.lax1dude.eaglercraft.v1_8.internal.buffer.WASMGCDirectArrayCopy; import net.lax1dude.eaglercraft.v1_8.internal.vfs2.VFile2; import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.BetterJSStringConverter; import net.lax1dude.eaglercraft.v1_8.internal.wasm_gc_teavm.WASMGCClientConfigAdapter; @@ -74,8 +74,10 @@ public class ServerPlatformSingleplayer { }else { MemoryStack.push(); try { - sendPacket0(BetterJSStringConverter.stringToJS(packet.channel), - WASMGCDirectArrayConverter.byteArrayToStackU8Array(packet.contents)); + int len = packet.contents.length; + Address addr = MemoryStack.malloc(len); + WASMGCDirectArrayCopy.memcpy(addr, packet.contents, 0, len); + sendPacket0(BetterJSStringConverter.stringToJS(packet.channel), addr, len); } finally { MemoryStack.pop(); } @@ -83,7 +85,7 @@ public class ServerPlatformSingleplayer { } @Import(module = "serverPlatformSingleplayer", name = "sendPacket") - private static native void sendPacket0(JSString channel, Uint8Array arr); + private static native void sendPacket0(JSString channel, Address addr, int length); public static List recieveAllPacket() { if(singleThreadMode) { diff --git a/src/wasm-gc-teavm/js/clientPlatformSingleplayer.js b/src/wasm-gc-teavm/js/clientPlatformSingleplayer.js index b81d3298..fda862c1 100755 --- a/src/wasm-gc-teavm/js/clientPlatformSingleplayer.js +++ b/src/wasm-gc-teavm/js/clientPlatformSingleplayer.js @@ -100,8 +100,13 @@ function initializeClientPlatfSP(spImports) { }); })); - const classesTEADBGCopy = new Int8Array(classesTEADBG.length); - classesTEADBGCopy.set(classesTEADBG, 0); + const transferList = []; + var classesTEADBGCopy = null; + + if(classesTEADBG) { + classesTEADBGCopy = classesTEADBG.buffer.slice(classesTEADBG.byteOffset, classesTEADBG.byteOffset + classesTEADBG.byteLength); + transferList.push(classesTEADBGCopy); + } var eagRuntimeJS; try { @@ -116,13 +121,15 @@ function initializeClientPlatfSP(spImports) { return false; } + transferList.push(eagRuntimeJS); + workerObj.postMessage({ "eaglercraftXOpts": eaglercraftXOpts, "eagruntimeJS": eagRuntimeJS, "classesWASM": classesWASMModule, "classesDeobfWASM": classesDeobfWASMModule, - "classesTEADBG": classesTEADBGCopy.buffer - }); + "classesTEADBG": classesTEADBGCopy + }, transferList); return true; }; @@ -131,16 +138,16 @@ function initializeClientPlatfSP(spImports) { /** * @param {string} channel - * @param {Uint8Array} arr + * @param {number} addr + * @param {number} length */ - spImports["sendPacket"] = function(channel, arr) { + spImports["sendPacket"] = function(channel, addr, length) { if(workerObj) { - const copiedArray = new Uint8Array(arr.length); - copiedArray.set(arr, 0); + const copiedArray = heapArrayBuffer.slice(addr, addr + length); workerObj.postMessage({ "ch": channel, - "dat": copiedArray.buffer - }, [copiedArray.buffer]); + "dat": copiedArray + }, [copiedArray]); } }; diff --git a/src/wasm-gc-teavm/js/eagruntime_entrypoint.js b/src/wasm-gc-teavm/js/eagruntime_entrypoint.js index cebdd6a9..a4c3b7d6 100755 --- a/src/wasm-gc-teavm/js/eagruntime_entrypoint.js +++ b/src/wasm-gc-teavm/js/eagruntime_entrypoint.js @@ -45,7 +45,7 @@ async function entryPoint() { const teavm = await wasmGC.load(classesWASM, { stackDeobfuscator: { - enabled: true, + enabled: !!(classesDeobfWASM && classesTEADBGURL), path: classesDeobfWASM, infoLocation: "external", externalInfoPath: classesTEADBGURL diff --git a/src/wasm-gc-teavm/js/eagruntime_main.js b/src/wasm-gc-teavm/js/eagruntime_main.js index a1a30bf0..eaa9bed2 100755 --- a/src/wasm-gc-teavm/js/eagruntime_main.js +++ b/src/wasm-gc-teavm/js/eagruntime_main.js @@ -106,6 +106,8 @@ var keepAliveCallback = null; var showDebugConsole = null; /** @type {function()|null} */ var resetSettings = null; +/** @type {function()|null} */ +var handleVisibilityChange = null; const runtimeOpts = { localStorageNamespace: "_eaglercraftX", diff --git a/src/wasm-gc-teavm/js/platformAudio.js b/src/wasm-gc-teavm/js/platformAudio.js index d965630f..5fa2bf35 100755 --- a/src/wasm-gc-teavm/js/platformAudio.js +++ b/src/wasm-gc-teavm/js/platformAudio.js @@ -16,6 +16,9 @@ const platfAudioName = "platformAudio"; +/** @type {HTMLAudioElement|null} */ +var silenceElement = null; + function setCurrentAudioContext(audioContext, audioImports) { /** @@ -26,25 +29,41 @@ function setCurrentAudioContext(audioContext, audioImports) { }; /** - * @param {Uint8Array} fileData + * @param {number} addr + * @param {number} length */ - audioImports["initKeepAliveHack"] = function(fileData) { - const copiedData = new Uint8Array(fileData.length); - copiedData.set(fileData, 0); + audioImports["initKeepAliveHack"] = function(addr, length) { + const copiedData = heapArrayBuffer.slice(addr, addr + length); const copiedDataURI = URL.createObjectURL(new Blob([copiedData], {type: "audio/wav"})); const audioElement = /** @type {HTMLAudioElement} */ (document.createElement("audio")); audioElement.classList.add("_eaglercraftX_keepalive_hack"); audioElement.setAttribute("style", "display:none;"); - audioElement.autoplay = true; + audioElement.autoplay = false; audioElement.loop = true; + audioElement.addEventListener("seeked", function() { + // NOP, wakes up the browser's event loop + }); + audioElement.addEventListener("canplay", function() { + if (silenceElement && document.visibilityState === "hidden") { + silenceElement.play(); + } + }); const sourceElement = /** @type {HTMLSourceElement} */ (document.createElement("source")); sourceElement.type = "audio/wav"; sourceElement.src = copiedDataURI; audioElement.appendChild(sourceElement); - audioElement.addEventListener("seeked", function() { - // NOP, wakes up the browser's event loop - }); parentElement.appendChild(audioElement); + silenceElement = audioElement; + }; + + handleVisibilityChange = function() { + if (silenceElement) { + if (document.visibilityState === "hidden") { + silenceElement.play(); + } else { + silenceElement.pause(); + } + } }; /** diff --git a/src/wasm-gc-teavm/js/platformFilesystem.js b/src/wasm-gc-teavm/js/platformFilesystem.js index a5fe387b..8a0d4f7f 100755 --- a/src/wasm-gc-teavm/js/platformFilesystem.js +++ b/src/wasm-gc-teavm/js/platformFilesystem.js @@ -144,13 +144,24 @@ function eaglerReadImpl(database, pathName) { eagruntimeImpl.platformFilesystem["eaglerRead"] = new WebAssembly.Suspending(eaglerReadImpl); +/** + * @param {IDBDatabase} database + * @param {string} pathName + * @param {number} addr + * @param {number} length + * @return {Promise} + */ +function eaglerWriteImpl(database, pathName, addr, length) { + return eaglerWriteImpl0(database, pathName, heapArrayBuffer.slice(addr, addr + length)); +} + /** * @param {IDBDatabase} database * @param {string} pathName * @param {ArrayBuffer} arr * @return {Promise} */ -function eaglerWriteImpl(database, pathName, arr) { +function eaglerWriteImpl0(database, pathName, arr) { return new Promise(function(resolve) { const tx = database.transaction("filesystem", "readwrite"); const r = tx.objectStore("filesystem").put(writeDBRow(pathName, arr)); @@ -193,7 +204,7 @@ eagruntimeImpl.platformFilesystem["eaglerExists"] = new WebAssembly.Suspending(e */ async function eaglerMoveImpl(database, pathNameOld, pathNameNew) { const oldData = await eaglerReadImpl(database, pathNameOld); - if(!oldData || !(await eaglerWriteImpl(database, pathNameNew, oldData))) { + if(!oldData || !(await eaglerWriteImpl0(database, pathNameNew, oldData))) { return false; } return await eaglerDeleteImpl(database, pathNameOld); @@ -209,7 +220,7 @@ eagruntimeImpl.platformFilesystem["eaglerMove"] = new WebAssembly.Suspending(eag */ async function eaglerCopyImpl(database, pathNameOld, pathNameNew) { const oldData = await eaglerReadImpl(database, pathNameOld); - return oldData && (await eaglerWriteImpl(database, pathNameNew, oldData)); + return oldData && (await eaglerWriteImpl0(database, pathNameNew, oldData)); } eagruntimeImpl.platformFilesystem["eaglerCopy"] = new WebAssembly.Suspending(eaglerCopyImpl); diff --git a/src/wasm-gc-teavm/js/platformInput.js b/src/wasm-gc-teavm/js/platformInput.js index f581f343..ffbe094a 100755 --- a/src/wasm-gc-teavm/js/platformInput.js +++ b/src/wasm-gc-teavm/js/platformInput.js @@ -118,7 +118,8 @@ async function initPlatformInput(inputImports) { blur: null, pointerlock: null, pointerlockerr: null, - fullscreenChange: null + fullscreenChange: null, + visibilitychange: null }; touchKeyboardOpenZone = document.createElement("div"); @@ -351,6 +352,11 @@ async function initPlatformInput(inputImports) { pushEvent(EVENT_TYPE_INPUT, EVENT_INPUT_FOCUS, null); }); + document.addEventListener("visibilitychange", currentEventListeners.visibilitychange = function(/** Event */ evt) { + if (handleVisibilityChange) + handleVisibilityChange(); + }); + /** * @param {number} evtType * @param {KeyboardEvent} evt @@ -1138,6 +1144,10 @@ async function initPlatformInput(inputImports) { window.removeEventListener("blur", /** @type {function(Event)} */ (currentEventListeners.blur)); currentEventListeners.blur = null; } + if(currentEventListeners.visibilitychange) { + document.removeEventListener("visibilitychange", currentEventListeners.visibilitychange); + currentEventListeners.visibilitychange = null; + } if(currentEventListeners.pointerlock) { document.removeEventListener("pointerlockchange", /** @type {function(Event)} */ (currentEventListeners.pointerlock)); currentEventListeners.pointerlock = null; diff --git a/src/wasm-gc-teavm/js/platformOpenGL.js b/src/wasm-gc-teavm/js/platformOpenGL.js index 3b3d9b04..a20fb8d0 100755 --- a/src/wasm-gc-teavm/js/platformOpenGL.js +++ b/src/wasm-gc-teavm/js/platformOpenGL.js @@ -99,7 +99,7 @@ function setCurrentGLContext(ctx, glesVersIn, allowExts, glImports) { glImports["glColorMask"] = ctx.colorMask.bind(ctx); glImports["glDrawBuffers"] = glesVersIn >= 300 ? ctx.drawBuffers.bind(ctx) : unsupportedFunc(platfOpenGLName, "glDrawBuffers"); glImports["glReadBuffer"] = glesVersIn >= 300 ? ctx.readBuffer.bind(ctx) : unsupportedFunc(platfOpenGLName, "glReadBuffer"); - glImports["glReadPixels"] = glImports["glReadPixels0"] = ctx.readPixels.bind(ctx); + glImports["glReadPixels"] = ctx.readPixels.bind(ctx); glImports["glPolygonOffset"] = ctx.polygonOffset.bind(ctx); glImports["glLineWidth"] = ctx.lineWidth.bind(ctx); glImports["glGenBuffers"] = ctx.createBuffer.bind(ctx); @@ -117,8 +117,8 @@ function setCurrentGLContext(ctx, glesVersIn, allowExts, glImports) { glImports["glDeleteRenderbuffer"] = ctx.deleteRenderbuffer.bind(ctx); glImports["glDeleteQueries"] = glesVersIn >= 300 ? ctx.deleteQuery.bind(ctx) : unsupportedFunc(platfOpenGLName, "glDeleteQueries"); glImports["glBindBuffer"] = ctx.bindBuffer.bind(ctx); - glImports["glBufferData"] = glImports["glBufferData0"] = ctx.bufferData.bind(ctx); - glImports["glBufferSubData"] = glImports["glBufferSubData0"] = ctx.bufferSubData.bind(ctx); + glImports["glBufferData"] = ctx.bufferData.bind(ctx); + glImports["glBufferSubData"] = ctx.bufferSubData.bind(ctx); glImports["glEnableVertexAttribArray"] = ctx.enableVertexAttribArray.bind(ctx); glImports["glDisableVertexAttribArray"] = ctx.disableVertexAttribArray.bind(ctx); glImports["glVertexAttribPointer"] = ctx.vertexAttribPointer.bind(ctx); @@ -126,9 +126,9 @@ function setCurrentGLContext(ctx, glesVersIn, allowExts, glImports) { glImports["glBindTexture"] = ctx.bindTexture.bind(ctx); glImports["glTexParameterf"] = ctx.texParameterf.bind(ctx); glImports["glTexParameteri"] = ctx.texParameteri.bind(ctx); - glImports["glTexImage3D"] = glImports["glTexImage3D0"] = glesVersIn >= 300 ? ctx.texImage3D.bind(ctx) : unsupportedFunc(platfOpenGLName, "glTexImage3D"); - glImports["glTexImage2D"] = glImports["glTexImage2D0"] = ctx.texImage2D.bind(ctx); - glImports["glTexSubImage2D"] = glImports["glTexSubImage2D0"] = ctx.texSubImage2D.bind(ctx); + glImports["glTexImage3D"] = glesVersIn >= 300 ? ctx.texImage3D.bind(ctx) : unsupportedFunc(platfOpenGLName, "glTexImage3D"); + glImports["glTexImage2D"] = ctx.texImage2D.bind(ctx); + glImports["glTexSubImage2D"] = ctx.texSubImage2D.bind(ctx); glImports["glCopyTexSubImage2D"] = ctx.copyTexSubImage2D.bind(ctx); glImports["glTexStorage2D"] = glesVersIn >= 300 ? ctx.texStorage2D.bind(ctx) : unsupportedFunc(platfOpenGLName, "glTexStorage2D"); glImports["glPixelStorei"] = ctx.pixelStorei.bind(ctx); @@ -145,6 +145,7 @@ function setCurrentGLContext(ctx, glesVersIn, allowExts, glImports) { glImports["glGetProgramInfoLog"] = ctx.getProgramInfoLog.bind(ctx); glImports["glDrawArrays"] = ctx.drawArrays.bind(ctx); glImports["glDrawElements"] = ctx.drawElements.bind(ctx); + glImports["glDrawRangeElements"] = glesVersIn >= 300 ? ctx.drawRangeElements.bind(ctx) : unsupportedFunc(platfOpenGLName, "glDrawRangeElements"); glImports["glBindAttribLocation"] = ctx.bindAttribLocation.bind(ctx); glImports["glGetAttribLocation"] = ctx.getAttribLocation.bind(ctx); glImports["glGetUniformLocation"] = ctx.getUniformLocation.bind(ctx); @@ -299,7 +300,6 @@ function setNoGLContext(glImports) { setUnsupportedFunc(glImports, platfOpenGLName, "glDrawBuffers"); setUnsupportedFunc(glImports, platfOpenGLName, "glReadBuffer"); setUnsupportedFunc(glImports, platfOpenGLName, "glReadPixels"); - setUnsupportedFunc(glImports, platfOpenGLName, "glReadPixels0"); setUnsupportedFunc(glImports, platfOpenGLName, "glPolygonOffset"); setUnsupportedFunc(glImports, platfOpenGLName, "glLineWidth"); setUnsupportedFunc(glImports, platfOpenGLName, "glGenBuffers"); @@ -318,9 +318,7 @@ function setNoGLContext(glImports) { setUnsupportedFunc(glImports, platfOpenGLName, "glDeleteQueries"); setUnsupportedFunc(glImports, platfOpenGLName, "glBindBuffer"); setUnsupportedFunc(glImports, platfOpenGLName, "glBufferData"); - setUnsupportedFunc(glImports, platfOpenGLName, "glBufferData0"); setUnsupportedFunc(glImports, platfOpenGLName, "glBufferSubData"); - setUnsupportedFunc(glImports, platfOpenGLName, "glBufferSubData0"); setUnsupportedFunc(glImports, platfOpenGLName, "glEnableVertexAttribArray"); setUnsupportedFunc(glImports, platfOpenGLName, "glDisableVertexAttribArray"); setUnsupportedFunc(glImports, platfOpenGLName, "glVertexAttribPointer"); @@ -329,11 +327,8 @@ function setNoGLContext(glImports) { setUnsupportedFunc(glImports, platfOpenGLName, "glTexParameterf"); setUnsupportedFunc(glImports, platfOpenGLName, "glTexParameteri"); setUnsupportedFunc(glImports, platfOpenGLName, "glTexImage3D"); - setUnsupportedFunc(glImports, platfOpenGLName, "glTexImage3D0"); setUnsupportedFunc(glImports, platfOpenGLName, "glTexImage2D"); - setUnsupportedFunc(glImports, platfOpenGLName, "glTexImage2D0"); setUnsupportedFunc(glImports, platfOpenGLName, "glTexSubImage2D"); - setUnsupportedFunc(glImports, platfOpenGLName, "glTexSubImage2D0"); setUnsupportedFunc(glImports, platfOpenGLName, "glCopyTexSubImage2D"); setUnsupportedFunc(glImports, platfOpenGLName, "glTexStorage2D"); setUnsupportedFunc(glImports, platfOpenGLName, "glPixelStorei"); @@ -350,6 +345,7 @@ function setNoGLContext(glImports) { setUnsupportedFunc(glImports, platfOpenGLName, "glGetProgramInfoLog"); setUnsupportedFunc(glImports, platfOpenGLName, "glDrawArrays"); setUnsupportedFunc(glImports, platfOpenGLName, "glDrawElements"); + setUnsupportedFunc(glImports, platfOpenGLName, "glDrawRangeElements"); setUnsupportedFunc(glImports, platfOpenGLName, "glBindAttribLocation"); setUnsupportedFunc(glImports, platfOpenGLName, "glGetAttribLocation"); setUnsupportedFunc(glImports, platfOpenGLName, "glGetUniformLocation"); diff --git a/src/wasm-gc-teavm/js/platformWebView.js b/src/wasm-gc-teavm/js/platformWebView.js index b1eb1501..dc144c98 100755 --- a/src/wasm-gc-teavm/js/platformWebView.js +++ b/src/wasm-gc-teavm/js/platformWebView.js @@ -121,19 +121,18 @@ function initializePlatfWebView(webViewImports) { /** * @param {string} ch - * @param {Uint8Array} bin + * @param {number} addr + * @param {number} length */ - webViewImports["sendBinaryMessage"] = function(ch, bin) { + webViewImports["sendBinaryMessage"] = function(ch, addr, length) { try { var w; if(currentIFrame != null && (w = currentIFrame.contentWindow) != null) { - const copiedArray = new Uint8Array(bin.length); - copiedArray.set(bin, 0); w.postMessage({ "ver": 1, "channel": ch, "type": "binary", - "data": copiedArray.buffer + "data": heapArrayBuffer.slice(addr, addr + length) }, "*"); }else { eagError("Server tried to send the WebView a message, but the message channel is not open!"); diff --git a/src/wasm-gc-teavm/js/serverPlatformSingleplayer.js b/src/wasm-gc-teavm/js/serverPlatformSingleplayer.js index b10ce741..f9e1b751 100755 --- a/src/wasm-gc-teavm/js/serverPlatformSingleplayer.js +++ b/src/wasm-gc-teavm/js/serverPlatformSingleplayer.js @@ -57,15 +57,15 @@ function initializeServerPlatfSP(spImports) { /** * @param {string} channel - * @param {Uint8Array} arr + * @param {number} addr + * @param {number} length */ - spImports["sendPacket"] = function(channel, arr) { - const copiedArray = new Uint8Array(arr.length); - copiedArray.set(arr, 0); + spImports["sendPacket"] = function(channel, addr, length) { + const copiedArray = heapArrayBuffer.slice(addr, addr + length); postMessage({ "ch": channel, - "dat": copiedArray.buffer - }, [copiedArray.buffer]); + "dat": copiedArray + }, [copiedArray]); }; spImports["getAvailablePackets"] = serverMessageQueue.getLength.bind(serverMessageQueue);