Update #28 - Added capes, voice chat, FNAW skins, and fixes

This commit is contained in:
lax1dude
2024-04-20 16:20:06 -07:00
parent 42c57894f9
commit ba88b52022
171 changed files with 7476 additions and 868 deletions

View File

@ -0,0 +1,172 @@
package net.lax1dude.eaglercraft.v1_8.opengl;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.IntBuffer;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.IResourceManagerReloadListener;
import net.minecraft.util.ResourceLocation;
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class EaglerMeshLoader implements IResourceManagerReloadListener {
private static final Logger logger = LogManager.getLogger("EaglerMeshLoader");
private static final Map<ResourceLocation, HighPolyMesh> meshCache = new HashMap();
public static HighPolyMesh getEaglerMesh(ResourceLocation meshLoc) {
if(meshLoc.cachedPointerType == ResourceLocation.CACHED_POINTER_EAGLER_MESH) {
return (HighPolyMesh)meshLoc.cachedPointer;
}
HighPolyMesh theMesh = meshCache.get(meshLoc);
if(theMesh == null) {
theMesh = new HighPolyMesh();
reloadMesh(meshLoc, theMesh, Minecraft.getMinecraft().getResourceManager());
}
meshLoc.cachedPointerType = ResourceLocation.CACHED_POINTER_EAGLER_MESH;
meshLoc.cachedPointer = theMesh;
return theMesh;
}
private static void reloadMesh(ResourceLocation meshLoc, HighPolyMesh meshStruct, IResourceManager resourceManager) {
IntBuffer up1 = null;
try {
int intsOfVertex, intsOfIndex, intsTotal, stride;
try(DataInputStream dis = new DataInputStream(resourceManager.getResource(meshLoc).getInputStream())) {
byte[] header = new byte[8];
dis.read(header);
if(!Arrays.equals(header, new byte[] { (byte) 33, (byte) 69, (byte) 65, (byte) 71, (byte) 36,
(byte) 109, (byte) 100, (byte) 108 })) {
throw new IOException("File is not an eaglercraft high-poly mesh!");
}
char CT = (char)dis.read();
if(CT == 'C') {
meshStruct.hasTexture = false;
}else if(CT == 'T') {
meshStruct.hasTexture = true;
}else {
throw new IOException("Unsupported mesh type '" + CT + "'!");
}
dis.skipBytes(dis.readUnsignedShort());
meshStruct.vertexCount = dis.readInt();
meshStruct.indexCount = dis.readInt();
int byteIndexCount = meshStruct.indexCount;
if(byteIndexCount % 2 != 0) { // must round up to int
byteIndexCount += 1;
}
stride = meshStruct.hasTexture ? 24 : 16;
intsOfVertex = meshStruct.vertexCount * stride / 4;
intsOfIndex = byteIndexCount / 2;
intsTotal = intsOfIndex + intsOfVertex;
up1 = EagRuntime.allocateIntBuffer(intsTotal);
for(int i = 0; i < intsTotal; ++i) {
int ch1 = dis.read();
int ch2 = dis.read();
int ch3 = dis.read();
int ch4 = dis.read();
if ((ch1 | ch2 | ch3 | ch4) < 0) throw new EOFException(); // rip
up1.put((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0));
}
}
if(meshStruct.vertexArray == null) {
meshStruct.vertexArray = _wglGenVertexArrays();
}
if(meshStruct.vertexBuffer == null) {
meshStruct.vertexBuffer = _wglGenBuffers();
}
if(meshStruct.indexBuffer == null) {
meshStruct.indexBuffer = _wglGenBuffers();
}
up1.position(0).limit(intsOfVertex);
EaglercraftGPU.bindGLArrayBuffer(meshStruct.vertexBuffer);
_wglBufferData(GL_ARRAY_BUFFER, up1, GL_STATIC_DRAW);
EaglercraftGPU.bindGLBufferArray(meshStruct.vertexArray);
up1.position(intsOfVertex).limit(intsTotal);
_wglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshStruct.indexBuffer);
_wglBufferData(GL_ELEMENT_ARRAY_BUFFER, up1, GL_STATIC_DRAW);
_wglEnableVertexAttribArray(0);
_wglVertexAttribPointer(0, 3, GL_FLOAT, false, stride, 0);
if(meshStruct.hasTexture) {
_wglEnableVertexAttribArray(1);
_wglVertexAttribPointer(1, 2, GL_FLOAT, false, stride, 16);
}
_wglEnableVertexAttribArray(meshStruct.hasTexture ? 2 : 1);
_wglVertexAttribPointer(meshStruct.hasTexture ? 2 : 1, 4, GL_BYTE, true, stride, 12);
}catch(Throwable ex) {
if(meshStruct.vertexArray != null) {
_wglDeleteVertexArrays(meshStruct.vertexArray);
meshStruct.vertexArray = null;
}
if(meshStruct.vertexBuffer != null) {
_wglDeleteBuffers(meshStruct.vertexBuffer);
meshStruct.vertexBuffer = null;
}
if(meshStruct.indexBuffer != null) {
_wglDeleteBuffers(meshStruct.indexBuffer);
meshStruct.indexBuffer = null;
}
meshStruct.vertexCount = 0;
meshStruct.indexCount = 0;
meshStruct.hasTexture = false;
logger.error("Failed to load eaglercraft high-poly mesh: \"{}\"", meshLoc);
logger.error(ex);
}finally {
if(up1 != null) {
EagRuntime.freeIntBuffer(up1);
}
}
}
@Override
public void onResourceManagerReload(IResourceManager var1) {
for(Entry<ResourceLocation, HighPolyMesh> meshEntry : meshCache.entrySet()) {
reloadMesh(meshEntry.getKey(), meshEntry.getValue(), var1);
}
}
}

View File

@ -23,7 +23,7 @@ import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
/**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -152,7 +152,7 @@ public class EaglercraftGPU {
currentList = null;
}
public static void glCallList(int displayList) {
public static final void glCallList(int displayList) {
DisplayList dp = mapDisplayListsGL.get(displayList);
if(dp == null) {
throw new NullPointerException("Tried to call a display list that does not exist: " + displayList);
@ -488,18 +488,28 @@ public class EaglercraftGPU {
return mapTexturesGL.get(tex);
}
public static final void drawHighPoly(HighPolyMesh mesh) {
if(mesh.vertexCount == 0 || mesh.indexCount == 0 || mesh.vertexArray == null) {
return;
}
FixedFunctionPipeline p = FixedFunctionPipeline.setupRenderDisplayList(mesh.getAttribBits()).update();
EaglercraftGPU.bindGLBufferArray(mesh.vertexArray);
p.drawElements(GL_TRIANGLES, mesh.indexCount, GL_UNSIGNED_SHORT, 0);
}
static boolean hasFramebufferHDR16FSupport = false;
static boolean hasFramebufferHDR32FSupport = false;
static boolean hasLinearHDR32FSupport = false;
public static void createFramebufferHDR16FTexture(int target, int level, int w, int h, int format, boolean allow32bitFallback) {
public static final void createFramebufferHDR16FTexture(int target, int level, int w, int h, int format, boolean allow32bitFallback) {
createFramebufferHDR16FTexture(target, level, w, h, format, allow32bitFallback, null);
}
public static void createFramebufferHDR16FTexture(int target, int level, int w, int h, int format, ByteBuffer pixelData) {
public static final void createFramebufferHDR16FTexture(int target, int level, int w, int h, int format, ByteBuffer pixelData) {
createFramebufferHDR16FTexture(target, level, w, h, format, false, pixelData);
}
private static void createFramebufferHDR16FTexture(int target, int level, int w, int h, int format, boolean allow32bitFallback, ByteBuffer pixelData) {
private static final void createFramebufferHDR16FTexture(int target, int level, int w, int h, int format, boolean allow32bitFallback, ByteBuffer pixelData) {
if(hasFramebufferHDR16FSupport) {
int internalFormat;
switch(format) {
@ -530,15 +540,15 @@ public class EaglercraftGPU {
}
}
public static void createFramebufferHDR32FTexture(int target, int level, int w, int h, int format, boolean allow16bitFallback) {
public static final void createFramebufferHDR32FTexture(int target, int level, int w, int h, int format, boolean allow16bitFallback) {
createFramebufferHDR32FTexture(target, level, w, h, format, allow16bitFallback, null);
}
public static void createFramebufferHDR32FTexture(int target, int level, int w, int h, int format, ByteBuffer pixelData) {
public static final void createFramebufferHDR32FTexture(int target, int level, int w, int h, int format, ByteBuffer pixelData) {
createFramebufferHDR32FTexture(target, level, w, h, format, false, pixelData);
}
private static void createFramebufferHDR32FTexture(int target, int level, int w, int h, int format, boolean allow16bitFallback, ByteBuffer pixelData) {
private static final void createFramebufferHDR32FTexture(int target, int level, int w, int h, int format, boolean allow16bitFallback, ByteBuffer pixelData) {
if(hasFramebufferHDR32FSupport) {
int internalFormat;
switch(format) {
@ -555,7 +565,7 @@ public class EaglercraftGPU {
default:
throw new UnsupportedOperationException("Unknown format: " + format);
}
_wglTexImage2D(target, level, internalFormat, w, h, 0, format, GL_FLOAT, pixelData);
_wglTexImage2Df32(target, level, internalFormat, w, h, 0, format, GL_FLOAT, pixelData);
}else {
if(allow16bitFallback) {
if(hasFramebufferHDR16FSupport) {
@ -585,7 +595,13 @@ public class EaglercraftGPU {
}else {
logger.error("32-bit HDR render target support: false");
}
if(!checkHasHDRFramebufferSupport()) {
hasLinearHDR32FSupport = PlatformOpenGL.checkLinearHDR32FSupport();
if(hasLinearHDR32FSupport) {
logger.info("32-bit HDR linear filter support: true");
}else {
logger.error("32-bit HDR linear filter support: false");
}
if(!checkHasHDRFramebufferSupportWithFilter()) {
logger.error("No HDR render target support was detected! Shaders will be disabled.");
}
DrawUtils.init();
@ -612,4 +628,12 @@ public class EaglercraftGPU {
public static final boolean checkHasHDRFramebufferSupport() {
return hasFramebufferHDR16FSupport || hasFramebufferHDR32FSupport;
}
public static final boolean checkHasHDRFramebufferSupportWithFilter() {
return hasFramebufferHDR16FSupport || (hasFramebufferHDR32FSupport && hasLinearHDR32FSupport);
}
public static final boolean checkLinearHDR32FSupport() {
return hasLinearHDR32FSupport;
}
}

View File

@ -11,7 +11,7 @@ import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
/**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -983,6 +983,30 @@ public class GlStateManager {
Matrix4f.mul(modeMatrix, paramMatrix, modeMatrix);
}
public static final void multMatrix(Matrix4f matrix) {
Matrix4f modeMatrix;
switch(stateMatrixMode) {
case GL_MODELVIEW:
default:
modeMatrix = modelMatrixStack[modelMatrixStackPointer];
modelMatrixStackAccessSerial[modelMatrixStackPointer] = ++modelMatrixAccessSerial;
break;
case GL_PROJECTION:
modeMatrix = projectionMatrixStack[projectionMatrixStackPointer];
projectionMatrixStackAccessSerial[projectionMatrixStackPointer] = ++projectionMatrixAccessSerial;
break;
case GL_TEXTURE:
int ptr = textureMatrixStackPointer[activeTexture];
modeMatrix = textureMatrixStack[activeTexture][ptr];
textureMatrixStackAccessSerial[activeTexture][textureMatrixStackPointer[activeTexture]] =
++textureMatrixAccessSerial[activeTexture];
break;
}
Matrix4f.mul(modeMatrix, matrix, modeMatrix);
}
public static final void color(float colorRed, float colorGreen, float colorBlue, float colorAlpha) {
stateColorR = colorRed;
stateColorG = colorGreen;

View File

@ -0,0 +1,66 @@
package net.lax1dude.eaglercraft.v1_8.opengl;
import net.lax1dude.eaglercraft.v1_8.internal.IBufferArrayGL;
import net.lax1dude.eaglercraft.v1_8.internal.IBufferGL;
import net.lax1dude.eaglercraft.v1_8.opengl.FixedFunctionShader.FixedFunctionState;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class HighPolyMesh {
IBufferArrayGL vertexArray;
IBufferGL vertexBuffer;
IBufferGL indexBuffer;
int vertexCount;
int indexCount;
boolean hasTexture;
public HighPolyMesh(IBufferArrayGL vertexArray, IBufferGL vertexBuffer, IBufferGL indexBuffer, int vertexCount,
int indexCount, boolean hasTexture) {
this.vertexArray = vertexArray;
this.vertexBuffer = vertexBuffer;
this.indexBuffer = indexBuffer;
this.vertexCount = vertexCount;
this.indexCount = indexCount;
this.hasTexture = hasTexture;
}
HighPolyMesh() {
}
public boolean isNull() {
return vertexArray == null;
}
public int getVertexCount() {
return vertexCount;
}
public int getIndexCount() {
return indexCount;
}
public boolean getHasTexture() {
return hasTexture;
}
public int getAttribBits() {
return hasTexture ? (FixedFunctionState.STATE_HAS_ATTRIB_TEXTURE | FixedFunctionState.STATE_HAS_ATTRIB_NORMAL) : FixedFunctionState.STATE_HAS_ATTRIB_NORMAL;
}
}

View File

@ -3984,11 +3984,11 @@ public class EaglerDeferredPipeline {
}
public static final boolean isSupported() {
return EaglercraftGPU.checkHasHDRFramebufferSupport();
return EaglercraftGPU.checkHasHDRFramebufferSupportWithFilter();
}
public static final String getReasonUnsupported() {
if(!EaglercraftGPU.checkHasHDRFramebufferSupport()) {
if(!EaglercraftGPU.checkHasHDRFramebufferSupportWithFilter()) {
return I18n.format("shaders.gui.unsupported.reason.hdrFramebuffer");
}else {
return null;