auto detect ANGLE issue at astartup

This commit is contained in:
LAX1DUDE 2022-08-21 16:11:34 -07:00
parent c25ab2610e
commit 37c9b4888d
5 changed files with 17774 additions and 17596 deletions
javascript
src
main/java/net/lax1dude/eaglercraft/glemu
teavm/java/net/lax1dude/eaglercraft/adapter

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -685,6 +685,9 @@ public class EaglerAdapterGL30 extends EaglerAdapterImpl2 {
}
public static final void glTexParameterf(int p1, int p2, float p3) {
if(p2 == GL_TEXTURE_MAX_ANISOTROPY && !anisotropicFilteringSupported()) {
return;
}
if (selectedTex == 0 && boundTexture0 != null && p2 == GL_TEXTURE_MAX_ANISOTROPY) {
boundTexture0.anisotropic = p3 > 1.0f;
}

@ -4,18 +4,180 @@ import static net.lax1dude.eaglercraft.adapter.teavm.WebGL2RenderingContext.*;
import org.teavm.jso.browser.Window;
import org.teavm.jso.dom.html.HTMLCanvasElement;
import org.teavm.jso.typedarrays.Float32Array;
import org.teavm.jso.typedarrays.Uint8Array;
import net.lax1dude.eaglercraft.adapter.teavm.WebGL2RenderingContext;
import net.lax1dude.eaglercraft.adapter.teavm.WebGLVertexArray;
import org.teavm.jso.webgl.*;
public class DetectAnisotropicGlitch {
public static boolean detectGlitch() {
//HTMLCanvasElement cvs = (HTMLCanvasElement) Window.current().getDocument().createElement("canvas");
//WebGL2RenderingContext ctx = (WebGL2RenderingContext) cvs.getContext("webgl2");
HTMLCanvasElement cvs = (HTMLCanvasElement) Window.current().getDocument().createElement("canvas");
cvs.setWidth(400);
cvs.setHeight(300);
WebGL2RenderingContext ctx = (WebGL2RenderingContext) cvs.getContext("webgl2");
if(ctx == null) {
Window.alert("WebGL 2 is not supported in this browser! Eaglercraft cannot start.");
throw new UnsupportedOperationException("WebGL 2 is not supported in this browser!");
}
if(ctx.getExtension("EXT_texture_filter_anisotropic") != null) {
String vshSrc = "#version 300 es\n"
+ "precision lowp float;"
+ "in vec2 a_pos;"
+ "out vec2 v_pos;"
+ "void main() {"
+ " gl_Position = vec4((v_pos = a_pos) * 2.0 - 1.0, 0.0, 1.0);"
+ "}";
String fshSrc = "#version 300 es\n"
+ "precision lowp float;"
+ "precision lowp sampler2D;"
+ "uniform sampler2D tex;"
+ "in vec2 v_pos;"
+ "out vec4 fragColor;"
+ "void main() {"
+ " fragColor = vec4(texture(tex, v_pos).rgb, 1.0);"
+ "}";
WebGLShader vsh = ctx.createShader(VERTEX_SHADER);
ctx.shaderSource(vsh, vshSrc);
ctx.compileShader(vsh);
if(!ctx.getShaderParameterb(vsh, COMPILE_STATUS)) {
System.err.println("ERROR: Could not check for ANGLE Issue #4994, VERTEX_SHADER did not compile:");
System.err.println(ctx.getShaderInfoLog(vsh));
ctx.deleteShader(vsh);
return false;
}
WebGLShader fsh = ctx.createShader(FRAGMENT_SHADER);
ctx.shaderSource(fsh, fshSrc);
ctx.compileShader(fsh);
if(!ctx.getShaderParameterb(fsh, COMPILE_STATUS)) {
System.err.println("ERROR: Could not check for ANGLE Issue #4994, FRAGMENT_SHADER did not compile:");
System.err.println(ctx.getShaderInfoLog(fsh));
ctx.deleteShader(vsh);
ctx.deleteShader(fsh);
return false;
}
WebGLProgram pr = ctx.createProgram();
ctx.attachShader(pr, vsh);
ctx.attachShader(pr, fsh);
ctx.bindAttribLocation(pr, 0, "a_pos");
ctx.bindAttribLocation(pr, 0, "fragColor");
ctx.linkProgram(pr);
ctx.detachShader(pr, vsh);
ctx.detachShader(pr, fsh);
ctx.deleteShader(vsh);
ctx.deleteShader(fsh);
if(!ctx.getProgramParameterb(pr, LINK_STATUS)) {
System.err.println("ERROR: Could not check for ANGLE Issue #4994, program did not link:");
System.err.println(ctx.getProgramInfoLog(pr));
ctx.deleteProgram(pr);
return false;
}
ctx.useProgram(pr);
ctx.uniform1i(ctx.getUniformLocation(pr, "tex"), 0);
byte x0 = (byte)0x00;
byte x1 = (byte)0xFF;
byte[] pixelsData = new byte[] {
x0, x0, x0, x1,
x0, x0, x0, x1,
x1, x1, x1, x1,
x0, x0, x0, x1,
x0, x0, x0, x1,
x0, x0, x0, x1,
x1, x1, x1, x1,
x0, x0, x0, x1,
x0, x0, x0, x1,
x0, x0, x0, x1,
x1, x1, x1, x1,
x0, x0, x0, x1
};
Uint8Array pixels = Uint8Array.create(pixelsData.length);
pixels.set(pixelsData);
WebGLTexture tex = ctx.createTexture();
ctx.bindTexture(TEXTURE_2D, tex);
ctx.texParameteri(TEXTURE_2D, TEXTURE_WRAP_S, REPEAT);
ctx.texParameteri(TEXTURE_2D, TEXTURE_WRAP_T, REPEAT);
ctx.texParameteri(TEXTURE_2D, TEXTURE_MIN_FILTER, NEAREST_MIPMAP_LINEAR);
ctx.texParameteri(TEXTURE_2D, TEXTURE_MAG_FILTER, NEAREST);
ctx.texParameterf(TEXTURE_2D, TEXTURE_MAX_ANISOTROPY_EXT, 16.0f);
ctx.texImage2D(TEXTURE_2D, 0, RGBA, 4, 3, 0, RGBA, UNSIGNED_BYTE, pixels);
ctx.generateMipmap(TEXTURE_2D);
float[] vertsData = new float[] {
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f
};
Float32Array verts = Float32Array.create(vertsData.length);
verts.set(vertsData);
WebGLBuffer buf = ctx.createBuffer();
ctx.bindBuffer(ARRAY_BUFFER, buf);
ctx.bufferData(ARRAY_BUFFER, verts, STATIC_DRAW);
WebGLVertexArray arr = ctx.createVertexArray();
ctx.bindVertexArray(arr);
ctx.enableVertexAttribArray(0);
ctx.vertexAttribPointer(0, 2, FLOAT, false, 8, 0);
ctx.viewport(0, 0, 400, 300);
ctx.drawArrays(TRIANGLES, 0, 6);
ctx.deleteVertexArray(arr);
ctx.deleteBuffer(buf);
ctx.deleteTexture(tex);
ctx.deleteProgram(pr);
Uint8Array readPx = Uint8Array.create(4);
ctx.readPixels(175, 150, 1, 1, RGBA, UNSIGNED_BYTE, readPx);
boolean b = (readPx.get(0) + readPx.get(1) + readPx.get(2)) != 0;
if(b) {
System.out.println("ANGLE issue #4994 is unpatched on this browser, enabling anisotropic fix");
}
return b;
}else {
System.err.println("WARNING: EXT_texture_filter_anisotropic is not supported!");
return false;
}
return EaglerAdapterImpl2.isWindows(); //TODO
}
}

@ -209,6 +209,7 @@ public class EaglerAdapterImpl2 {
private static EventListener wheel = null;
private static String[] identifier = new String[0];
private static String integratedServerScript = "worker_bootstrap.js";
private static boolean anisotropicFilteringSupported = false;
public static final String[] getIdentifier() {
return identifier;
@ -265,7 +266,7 @@ public class EaglerAdapterImpl2 {
//String agent = getString("window.navigator.userAgent").toLowerCase();
//if(agent.contains("windows")) isAnisotropicPatched = false;
webgl.getExtension("EXT_texture_filter_anisotropic");
anisotropicFilteringSupported = webgl.getExtension("EXT_texture_filter_anisotropic") != null;
win.addEventListener("contextmenu", contextmenu = new EventListener<MouseEvent>() {
@Override
@ -633,6 +634,9 @@ public class EaglerAdapterImpl2 {
}
}
public static final boolean anisotropicFilteringSupported() {
return anisotropicFilteringSupported;
}
public static final void _wglEnable(int p1) {
webgl.enable(p1);
}
@ -975,7 +979,7 @@ public class EaglerAdapterImpl2 {
return getNavString("platform").toLowerCase().contains("win");
}
public static final boolean glNeedsAnisotropicFix() {
return DetectAnisotropicGlitch.detectGlitch();
return anisotropicFilteringSupported && DetectAnisotropicGlitch.detectGlitch();
}
private static HTMLCanvasElement imageLoadCanvas = null;