Update #51 - Protocol and FPS improvements, better workspace

This commit is contained in:
lax1dude
2025-05-18 15:01:06 -07:00
parent 71c61e33fd
commit 325a6826bf
1191 changed files with 9266 additions and 187695 deletions

View File

@ -21,6 +21,7 @@ import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import java.util.List;
import net.lax1dude.eaglercraft.v1_8.Display;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.IVertexArrayGL;
import net.lax1dude.eaglercraft.v1_8.internal.IBufferGL;
@ -78,6 +79,7 @@ public class DrawUtils {
_wglCompileShader(vshLocal);
if(_wglGetShaderi(vshLocal, GL_COMPILE_STATUS) != GL_TRUE) {
Display.checkContextLost();
EaglercraftGPU.logger.error("Failed to compile GL_VERTEX_SHADER \"" + vertexShaderPath + "\"!");
String log = _wglGetShaderInfoLog(vshLocal);
if(log != null) {

View File

@ -47,6 +47,11 @@ public class EaglercraftGPU {
return _wglGenBuffers();
}
@Override
protected void invalidate(IBufferGL object) {
// Don't bother
}
@Override
protected void destroy(IBufferGL object) {
_wglDeleteBuffers(object);
@ -61,6 +66,11 @@ public class EaglercraftGPU {
return _wglGenBuffers();
}
@Override
protected void invalidate(IBufferGL object) {
// Don't bother
}
@Override
protected void destroy(IBufferGL object) {
_wglDeleteBuffers(object);
@ -68,13 +78,32 @@ public class EaglercraftGPU {
};
static final GLObjectRecycler<IVertexArrayGL> VAORecycler = new GLObjectRecycler<IVertexArrayGL>(128) {
static final GLObjectRecycler<IVertexArrayGL> VAORecycler = new GLObjectRecycler<IVertexArrayGL>(256) {
@Override
protected IVertexArrayGL create() {
return _wglGenVertexArrays();
}
@Override
protected void invalidate(IVertexArrayGL object) {
int i;
int bits = object.getBits();
if(bits != 0) {
IVertexArrayGL old = currentVertexArray;
if (old != object) {
_wglBindVertexArray(object);
}
do {
i = Integer.numberOfTrailingZeros(bits);
_wglDisableVertexAttribArray(i);
} while((bits &= ~((i << 1) - 1)) != 0);
if (old != object) {
_wglBindVertexArray(old);
}
}
}
@Override
protected void destroy(IVertexArrayGL object) {
_wglDeleteVertexArrays(object);
@ -186,7 +215,7 @@ public class EaglercraftGPU {
dp.bindQuad32 = false;
}
if(dp.vertexBuffer == null) {
dp.vertexBuffer = _wglGenBuffers();
dp.vertexBuffer = createGLArrayBuffer();
}
bindVAOGLArrayBufferNow(dp.vertexBuffer);
@ -250,7 +279,7 @@ public class EaglercraftGPU {
bindGLVertexArray(dp.vertexArray);
if(dp.mode == GL_QUADS) {
int cnt = dp.count;
if(cnt > 0xFFFF) {
if(cnt > quad16MaxVertices) {
if(!dp.bindQuad32) {
dp.bindQuad16 = false;
dp.bindQuad32 = true;
@ -258,16 +287,14 @@ public class EaglercraftGPU {
}else {
attachQuad32EmulationBuffer(cnt, false);
}
p.drawElements(GL_TRIANGLES, cnt + (cnt >> 1), GL_UNSIGNED_INT, 0);
p.drawElements(GL_TRIANGLES, (cnt >> 2) * 6, GL_UNSIGNED_INT, 0);
}else {
if(!dp.bindQuad16) {
dp.bindQuad16 = true;
dp.bindQuad32 = false;
attachQuad16EmulationBuffer(cnt, true);
}else {
attachQuad16EmulationBuffer(cnt, false);
attachQuad16EmulationBuffer(true);
}
p.drawElements(GL_TRIANGLES, cnt + (cnt >> 1), GL_UNSIGNED_SHORT, 0);
p.drawElements(GL_TRIANGLES, (cnt >> 2) * 6, GL_UNSIGNED_SHORT, 0);
}
}else {
p.drawArrays(dp.mode, 0, dp.count);
@ -436,7 +463,7 @@ public class EaglercraftGPU {
}
public static void destroyGLArrayBuffer(IBufferGL buffer) {
arrayBufferRecycler.destroy(buffer);
arrayBufferRecycler.destroyObject(buffer);
}
public static IBufferGL createGLElementArrayBuffer() {
@ -444,7 +471,7 @@ public class EaglercraftGPU {
}
public static void destroyGLElementArrayBuffer(IBufferGL buffer) {
elementArrayBufferRecycler.destroy(buffer);
elementArrayBufferRecycler.destroyObject(buffer);
}
public static boolean areVAOsEmulated() {
@ -461,7 +488,7 @@ public class EaglercraftGPU {
public static void destroyGLVertexArray(IVertexArrayGL buffer) {
if(!emulatedVAOs) {
VAORecycler.destroy(buffer);
VAORecycler.destroyObject(buffer);
}
}
@ -694,7 +721,7 @@ public class EaglercraftGPU {
public static final int CLEAR_BINDING_TEXTURE = 1;
public static final int CLEAR_BINDING_TEXTURE0 = 2;
public static final int CLEAR_BINDING_ACTIVE_TEXTURE = 4;
public static final int CLEAR_BINDING_BUFFER_ARRAY = 8;
public static final int CLEAR_BINDING_VERTEX_ARRAY = 8;
public static final int CLEAR_BINDING_ARRAY_BUFFER = 16;
public static final int CLEAR_BINDING_SHADER_PROGRAM = 32;
@ -712,7 +739,7 @@ public class EaglercraftGPU {
GlStateManager.activeTexture = 0;
_wglActiveTexture(GL_TEXTURE0);
}
if((mask & CLEAR_BINDING_BUFFER_ARRAY) != 0) {
if((mask & CLEAR_BINDING_VERTEX_ARRAY) != 0) {
currentVertexArray = null;
}
if((mask & CLEAR_BINDING_ARRAY_BUFFER) != 0) {
@ -757,11 +784,11 @@ public class EaglercraftGPU {
private static long lastRecyclerFlush = 0l;
public static void optimize() {
FixedFunctionPipeline.optimize();
long millis = EagRuntime.steadyTimeMillis();
if(millis - lastRecyclerFlush > 120000l) {
lastRecyclerFlush = millis;
arrayBufferRecycler.compact();
elementArrayBufferRecycler.compact();
VAORecycler.compact();
}
}
@ -778,34 +805,21 @@ public class EaglercraftGPU {
lastRender.update().drawDirectArrays(lastMode, 0, lastCount);
}
public static final int quad16MaxVertices = 65536;
private static IBufferGL quad16EmulationBuffer = null;
private static int quad16EmulationBufferSize = 0;
private static IBufferGL quad32EmulationBuffer = null;
private static int quad32EmulationBufferSize = 0;
public static void attachQuad16EmulationBuffer(int vertexCount, boolean bind) {
public static void attachQuad16EmulationBuffer(boolean bind) {
IBufferGL buf = quad16EmulationBuffer;
if(buf == null) {
quad16EmulationBuffer = buf = _wglGenBuffers();
int newSize = quad16EmulationBufferSize = (vertexCount & 0xFFFFF000) + 0x2000;
if(newSize > 0xFFFF) {
newSize = 0xFFFF;
}
EaglercraftGPU.bindVAOGLElementArrayBufferNow(buf);
resizeQuad16EmulationBuffer(newSize >> 2);
}else {
int cnt = quad16EmulationBufferSize;
if(cnt < vertexCount) {
int newSize = quad16EmulationBufferSize = (vertexCount & 0xFFFFF000) + 0x2000;
if(newSize > 0xFFFF) {
newSize = 0xFFFF;
}
EaglercraftGPU.bindVAOGLElementArrayBufferNow(buf);
resizeQuad16EmulationBuffer(newSize >> 2);
}else if(bind) {
EaglercraftGPU.bindVAOGLElementArrayBuffer(buf);
}
resizeQuad16EmulationBuffer(quad16MaxVertices >> 2);
}else if(bind) {
EaglercraftGPU.bindVAOGLElementArrayBuffer(buf);
}
}
@ -813,13 +827,13 @@ public class EaglercraftGPU {
IBufferGL buf = quad32EmulationBuffer;
if(buf == null) {
quad32EmulationBuffer = buf = _wglGenBuffers();
int newSize = quad32EmulationBufferSize = (vertexCount & 0xFFFFC000) + 0x8000;
int newSize = quad32EmulationBufferSize = (vertexCount + 0xFFFF) & 0xFFFF0000;
EaglercraftGPU.bindVAOGLElementArrayBufferNow(buf);
resizeQuad32EmulationBuffer(newSize >> 2);
}else {
int cnt = quad32EmulationBufferSize;
if(cnt < vertexCount) {
int newSize = quad32EmulationBufferSize = (vertexCount & 0xFFFFC000) + 0x8000;
int newSize = quad32EmulationBufferSize = (vertexCount + 0xFFFF) & 0xFFFF0000;
EaglercraftGPU.bindVAOGLElementArrayBufferNow(buf);
resizeQuad32EmulationBuffer(newSize >> 2);
}else if(bind) {

View File

@ -26,6 +26,9 @@ import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import net.lax1dude.eaglercraft.v1_8.Display;
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
@ -41,8 +44,9 @@ public class EffectPipelineFXAA {
private static final int _GL_RENDERBUFFER = 0x8D41;
private static final int _GL_COLOR_ATTACHMENT0 = 0x8CE0;
private static final int _GL_DEPTH_ATTACHMENT = 0x8D00;
private static final int _GL_DEPTH_COMPONENT16 = 0x81A5;
private static final int _GL_DEPTH_COMPONENT32F = 0x8CAC;
private static final int _GL_DEPTH_STENCIL_ATTACHMENT = 0x821A;
private static final int _GL_DEPTH_STENCIL = 0x84F9;
private static IProgramGL shaderProgram = null;
private static IUniformGL u_screenSize2f = null;
@ -63,6 +67,7 @@ public class EffectPipelineFXAA {
_wglCompileShader(frag);
if(_wglGetShaderi(frag, GL_COMPILE_STATUS) != GL_TRUE) {
Display.checkContextLost();
logger.error("Failed to compile GL_FRAGMENT_SHADER \"" + fragmentShaderPath + "\" for EffectPipelineFXAA!");
String log = _wglGetShaderInfoLog(frag);
if(log != null) {
@ -91,6 +96,7 @@ public class EffectPipelineFXAA {
_wglDeleteShader(frag);
if(_wglGetProgrami(shaderProgram, GL_LINK_STATUS) != GL_TRUE) {
Display.checkContextLost();
logger.error("Failed to link shader program for EffectPipelineFXAA!");
String log = _wglGetProgramInfoLog(shaderProgram);
if(log != null) {
@ -121,8 +127,11 @@ public class EffectPipelineFXAA {
_wglBindRenderbuffer(_GL_RENDERBUFFER, framebufferDepth);
_wglBindFramebuffer(_GL_FRAMEBUFFER, framebuffer);
_wglFramebufferTexture2D(_GL_FRAMEBUFFER, _GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, EaglercraftGPU.getNativeTexture(framebufferColor), 0);
_wglFramebufferRenderbuffer(_GL_FRAMEBUFFER, _GL_DEPTH_ATTACHMENT, _GL_RENDERBUFFER, framebufferDepth);
_wglFramebufferTexture2D(_GL_FRAMEBUFFER, _GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
EaglercraftGPU.getNativeTexture(framebufferColor), 0);
_wglFramebufferRenderbuffer(_GL_FRAMEBUFFER,
EaglercraftGPU.checkOpenGLESVersion() == 200 ? _GL_DEPTH_STENCIL_ATTACHMENT : _GL_DEPTH_ATTACHMENT,
_GL_RENDERBUFFER, framebufferDepth);
_wglBindFramebuffer(_GL_FRAMEBUFFER, null);
}
@ -136,7 +145,8 @@ public class EffectPipelineFXAA {
EaglercraftGPU.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (ByteBuffer)null);
_wglBindRenderbuffer(_GL_RENDERBUFFER, framebufferDepth);
_wglRenderbufferStorage(_GL_RENDERBUFFER, EaglercraftGPU.checkOpenGLESVersion() == 200 ? _GL_DEPTH_COMPONENT16 : _GL_DEPTH_COMPONENT32F, width, height);
_wglRenderbufferStorage(_GL_RENDERBUFFER, EaglercraftGPU.checkOpenGLESVersion() == 200 ? _GL_DEPTH_STENCIL
: _GL_DEPTH_COMPONENT32F, width, height);
}
_wglBindFramebuffer(_GL_FRAMEBUFFER, framebuffer);

View File

@ -24,7 +24,7 @@ import java.util.List;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.FloatBuffer;
import net.lax1dude.eaglercraft.v1_8.Display;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.IVertexArrayGL;
import net.lax1dude.eaglercraft.v1_8.internal.IProgramGL;
@ -153,7 +153,7 @@ public class FixedFunctionPipeline {
EaglercraftGPU.bindGLShaderProgram(shaderProgram);
if(mode == GL_QUADS) {
StreamBufferInstance sb = currentVertexArray;
if(count > 0xFFFF) {
if(count > EaglercraftGPU.quad16MaxVertices) {
if(!sb.bindQuad32) {
sb.bindQuad16 = false;
sb.bindQuad32 = true;
@ -161,18 +161,14 @@ public class FixedFunctionPipeline {
}else {
EaglercraftGPU.attachQuad32EmulationBuffer(count, false);
}
EaglercraftGPU.drawElements(GL_TRIANGLES, count + (count >> 1),
GL_UNSIGNED_INT, 0);
EaglercraftGPU.drawElements(GL_TRIANGLES, (count >> 2) * 6, GL_UNSIGNED_INT, 0);
}else {
if(!sb.bindQuad16) {
sb.bindQuad16 = true;
sb.bindQuad32 = false;
EaglercraftGPU.attachQuad16EmulationBuffer(count, true);
}else {
EaglercraftGPU.attachQuad16EmulationBuffer(count, false);
EaglercraftGPU.attachQuad16EmulationBuffer(true);
}
EaglercraftGPU.drawElements(GL_TRIANGLES, count + (count >> 1),
GL_UNSIGNED_SHORT, 0);
EaglercraftGPU.drawElements(GL_TRIANGLES, (count >> 2) * 6, GL_UNSIGNED_SHORT, 0);
}
}else {
EaglercraftGPU.drawArrays(mode, offset, count);
@ -291,6 +287,7 @@ public class FixedFunctionPipeline {
_wglCompileShader(vsh);
if(_wglGetShaderi(vsh, GL_COMPILE_STATUS) != GL_TRUE) {
Display.checkContextLost();
LOGGER.error("Failed to compile GL_VERTEX_SHADER for state {} !", (visualizeBits(coreBits) + (enableExt && extBits != 0 ? " ext " + visualizeBits(extBits) : "")));
String log = _wglGetShaderInfoLog(vsh);
if(log != null) {
@ -309,6 +306,7 @@ public class FixedFunctionPipeline {
_wglCompileShader(fsh);
if(_wglGetShaderi(fsh, GL_COMPILE_STATUS) != GL_TRUE) {
Display.checkContextLost();
LOGGER.error("Failed to compile GL_FRAGMENT_SHADER for state {} !", (visualizeBits(coreBits) + (enableExt && extBits != 0 ? " ext " + visualizeBits(extBits) : "")));
String log = _wglGetShaderInfoLog(fsh);
if(log != null) {
@ -563,6 +561,7 @@ public class FixedFunctionPipeline {
_wglLinkProgram(compiledProg);
if(_wglGetProgrami(compiledProg, GL_LINK_STATUS) != GL_TRUE) {
Display.checkContextLost();
LOGGER.error("Program could not be linked for state {} !", (visualizeBits(bits) + (extensionProvider != null && extBits != 0 ? " ext " + visualizeBits(extBits) : "")));
String log = _wglGetProgramInfoLog(compiledProg);
if(log != null) {
@ -574,8 +573,7 @@ public class FixedFunctionPipeline {
throw new IllegalStateException("Program could not be linked!");
}
streamBuffer = new StreamBuffer(FixedFunctionShader.initialSize, FixedFunctionShader.initialCount,
FixedFunctionShader.maxCount, (vertexArray, vertexBuffer) -> {
streamBuffer = new StreamBuffer((vertexArray, vertexBuffer) -> {
EaglercraftGPU.bindGLVertexArray(vertexArray);
EaglercraftGPU.bindVAOGLArrayBuffer(vertexBuffer);
@ -1063,12 +1061,6 @@ public class FixedFunctionPipeline {
return this;
}
static void optimize() {
for(int i = 0, l = pipelineListTracker.size(); i < l; ++i) {
pipelineListTracker.get(i).streamBuffer.optimize();
}
}
public static void flushCache() {
shaderSourceCacheVSH = null;
shaderSourceCacheFSH = null;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
* Copyright (c) 2022-2023 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
@ -18,10 +18,6 @@ package net.lax1dude.eaglercraft.v1_8.opengl;
public class FixedFunctionShader {
public static final int initialSize = 0x8000;
public static final int initialCount = 3;
public static final int maxCount = 8;
public class FixedFunctionState {
public static final int fixedFunctionStatesCount = 12;

View File

@ -40,6 +40,7 @@ public abstract class GLObjectRecycler<T> {
}
public void destroyObject(T obj) {
invalidate(obj);
deletedObjects.addLast(obj);
}
@ -51,6 +52,8 @@ public abstract class GLObjectRecycler<T> {
protected abstract T create();
protected abstract void invalidate(T object);
protected abstract void destroy(T object);
}

View File

@ -19,6 +19,7 @@ package net.lax1dude.eaglercraft.v1_8.opengl;
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import net.lax1dude.eaglercraft.v1_8.Display;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.IVertexArrayGL;
import net.lax1dude.eaglercraft.v1_8.internal.IBufferGL;
@ -91,6 +92,7 @@ public class InstancedFontRenderer {
_wglCompileShader(vert);
if(_wglGetShaderi(vert, GL_COMPILE_STATUS) != GL_TRUE) {
Display.checkContextLost();
logger.error("Failed to compile GL_VERTEX_SHADER \"" + vertexShaderPath + "\" for InstancedFontRenderer!");
String log = _wglGetShaderInfoLog(vert);
if(log != null) {
@ -106,6 +108,7 @@ public class InstancedFontRenderer {
_wglCompileShader(frag);
if(_wglGetShaderi(frag, GL_COMPILE_STATUS) != GL_TRUE) {
Display.checkContextLost();
logger.error("Failed to compile GL_FRAGMENT_SHADER \"" + fragmentShaderPath + "\" for InstancedFontRenderer!");
String log = _wglGetShaderInfoLog(frag);
if(log != null) {
@ -135,6 +138,7 @@ public class InstancedFontRenderer {
_wglDeleteShader(frag);
if(_wglGetProgrami(shaderProgram, GL_LINK_STATUS) != GL_TRUE) {
Display.checkContextLost();
logger.error("Failed to link shader program for InstancedFontRenderer!");
String log = _wglGetProgramInfoLog(shaderProgram);
if(log != null) {
@ -203,7 +207,7 @@ public class InstancedFontRenderer {
EaglercraftGPU.vertexAttribDivisor(0, 0);
EaglercraftGPU.bindVAOGLArrayBufferNow(instancesBuffer);
_wglBufferData(GL_ARRAY_BUFFER, fontDataBuffer.remaining(), GL_STREAM_DRAW);
_wglBufferData(GL_ARRAY_BUFFER, fontDataBuffer.capacity(), GL_STREAM_DRAW);
EaglercraftGPU.enableVertexAttribArray(1);
EaglercraftGPU.vertexAttribPointer(1, 2, GL_SHORT, false, 10, 0);
@ -377,6 +381,7 @@ public class InstancedFontRenderer {
int l = fontDataBuffer.limit();
fontDataBuffer.flip();
_wglBufferData(GL_ARRAY_BUFFER, fontDataBuffer.capacity(), GL_STREAM_DRAW);
_wglBufferSubData(GL_ARRAY_BUFFER, 0, fontDataBuffer);
fontDataBuffer.position(p);
@ -390,6 +395,7 @@ public class InstancedFontRenderer {
int l = fontBoldDataBuffer.limit();
fontBoldDataBuffer.flip();
_wglBufferData(GL_ARRAY_BUFFER, fontBoldDataBuffer.capacity(), GL_STREAM_DRAW);
_wglBufferSubData(GL_ARRAY_BUFFER, 0, fontBoldDataBuffer);
fontBoldDataBuffer.position(p);

View File

@ -19,6 +19,7 @@ package net.lax1dude.eaglercraft.v1_8.opengl;
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import net.lax1dude.eaglercraft.v1_8.Display;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.IVertexArrayGL;
import net.lax1dude.eaglercraft.v1_8.internal.IBufferGL;
@ -92,6 +93,7 @@ public class InstancedParticleRenderer {
_wglCompileShader(vert);
if(_wglGetShaderi(vert, GL_COMPILE_STATUS) != GL_TRUE) {
Display.checkContextLost();
logger.error("Failed to compile GL_VERTEX_SHADER \"" + vertexShaderPath + "\" for InstancedParticleRenderer!");
String log = _wglGetShaderInfoLog(vert);
if(log != null) {
@ -107,6 +109,7 @@ public class InstancedParticleRenderer {
_wglCompileShader(frag);
if(_wglGetShaderi(frag, GL_COMPILE_STATUS) != GL_TRUE) {
Display.checkContextLost();
logger.error("Failed to compile GL_FRAGMENT_SHADER \"" + fragmentShaderPath + "\" for InstancedParticleRenderer!");
String log = _wglGetShaderInfoLog(frag);
if(log != null) {
@ -136,6 +139,7 @@ public class InstancedParticleRenderer {
_wglDeleteShader(frag);
if(_wglGetProgrami(shaderProgram, GL_LINK_STATUS) != GL_TRUE) {
Display.checkContextLost();
logger.error("Failed to link shader program for InstancedParticleRenderer!");
String log = _wglGetProgramInfoLog(shaderProgram);
if(log != null) {
@ -184,7 +188,7 @@ public class InstancedParticleRenderer {
EaglercraftGPU.vertexAttribDivisor(0, 0);
EaglercraftGPU.bindVAOGLArrayBufferNow(instancesBuffer);
_wglBufferData(GL_ARRAY_BUFFER, particleBuffer.remaining(), GL_STREAM_DRAW);
_wglBufferData(GL_ARRAY_BUFFER, particleBuffer.capacity(), GL_STREAM_DRAW);
EaglercraftGPU.enableVertexAttribArray(1);
EaglercraftGPU.vertexAttribPointer(1, 3, GL_FLOAT, false, 24, 0);
@ -311,6 +315,7 @@ public class InstancedParticleRenderer {
int l = particleBuffer.limit();
particleBuffer.flip();
_wglBufferData(GL_ARRAY_BUFFER, particleBuffer.capacity(), GL_STREAM_DRAW);
_wglBufferSubData(GL_ARRAY_BUFFER, 0, particleBuffer);
particleBuffer.position(p);

View File

@ -223,4 +223,17 @@ class SoftGLVertexArray implements IVertexArrayGL {
}
@Override
public int getBits() {
return enabled;
}
@Override
public void setBit(int bit) {
}
@Override
public void unsetBit(int bit) {
}
}

View File

@ -22,6 +22,7 @@ import java.util.List;
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
import net.lax1dude.eaglercraft.v1_8.Display;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.IProgramGL;
import net.lax1dude.eaglercraft.v1_8.internal.IShaderGL;
@ -78,6 +79,7 @@ public class SpriteLevelMixer {
_wglCompileShader(frag);
if(_wglGetShaderi(frag, GL_COMPILE_STATUS) != GL_TRUE) {
Display.checkContextLost();
LOGGER.error("Failed to compile GL_FRAGMENT_SHADER \"" + fragmentShaderPath + "\" for SpriteLevelMixer!");
String log = _wglGetShaderInfoLog(frag);
if(log != null) {
@ -106,6 +108,7 @@ public class SpriteLevelMixer {
_wglDeleteShader(frag);
if(_wglGetProgrami(shaderProgram, GL_LINK_STATUS) != GL_TRUE) {
Display.checkContextLost();
LOGGER.error("Failed to link shader program for SpriteLevelMixer!");
String log = _wglGetProgramInfoLog(shaderProgram);
if(log != null) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023-2024 lax1dude. All Rights Reserved.
* Copyright (c) 2023-2025 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
@ -24,11 +24,7 @@ import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
public class StreamBuffer {
public static final int poolSize = 16;
public final int initialSize;
public final int initialCount;
public final int maxCount;
public static final int poolSize = 4;
protected static final PoolInstance[] pool = new PoolInstance[poolSize];
protected static int poolBufferID = 0;
@ -55,21 +51,23 @@ public class StreamBuffer {
}
private static void resizeInstance(PoolInstance instance, int requiredMemory) {
if(instance.vertexBuffer == null) {
instance.vertexBuffer = _wglGenBuffers();
IBufferGL buffer = instance.vertexBuffer;
if (buffer == null) {
buffer = _wglGenBuffers();
instance.vertexBuffer = buffer;
}
if(instance.vertexBufferSize < requiredMemory) {
int newSize = (requiredMemory & 0xFFFFF000) + 0x2000;
EaglercraftGPU.bindGLArrayBuffer(instance.vertexBuffer);
_wglBufferData(GL_ARRAY_BUFFER, newSize, GL_STREAM_DRAW);
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);
}
protected StreamBufferInstance[] buffers;
protected int currentBufferId = 0;
protected int overflowCounter = 0;
protected final IStreamBufferInitializer initializer;
@ -95,19 +93,20 @@ public class StreamBuffer {
void initialize(IVertexArrayGL vertexArray, IBufferGL vertexBuffer);
}
public StreamBuffer(int initialSize, int initialCount, int maxCount, IStreamBufferInitializer initializer) {
if(maxCount > poolSize) {
maxCount = poolSize;
public StreamBuffer(IStreamBufferInitializer initializer) {
this(poolSize, initializer);
}
public StreamBuffer(int count, IStreamBufferInitializer initializer) {
if(count > poolSize) {
count = poolSize;
}
this.buffers = new StreamBufferInstance[initialCount];
this.buffers = new StreamBufferInstance[count];
for(int i = 0; i < this.buffers.length; ++i) {
StreamBufferInstance j = new StreamBufferInstance();
j.poolInstance = fillPoolInstance();
this.buffers[i] = j;
}
this.initialSize = initialSize;
this.initialCount = initialCount;
this.maxCount = maxCount;
this.initializer = initializer;
}
@ -121,67 +120,6 @@ public class StreamBuffer {
return next;
}
public void optimize() {
overflowCounter += currentBufferId - buffers.length;
if(overflowCounter < -25) {
int newCount = buffers.length - 1 + ((overflowCounter + 25) / 5);
if(newCount < initialCount) {
newCount = initialCount;
}
if(newCount < buffers.length) {
StreamBufferInstance[] newArray = new StreamBufferInstance[newCount];
for(int i = 0; i < buffers.length; ++i) {
if(i < newArray.length) {
newArray[i] = buffers[i];
}else {
if(buffers[i].vertexArray != null) {
EaglercraftGPU.destroyGLVertexArray(buffers[i].vertexArray);
}
}
}
buffers = newArray;
refill();
}
overflowCounter = 0;
}else if(overflowCounter > 15) {
int newCount = buffers.length + 1 + ((overflowCounter - 15) / 5);
if(newCount > maxCount) {
newCount = maxCount;
}
if(newCount > buffers.length) {
StreamBufferInstance[] newArray = new StreamBufferInstance[newCount];
for(int i = 0; i < newArray.length; ++i) {
if(i < buffers.length) {
newArray[i] = buffers[i];
}else {
newArray[i] = new StreamBufferInstance();
}
}
buffers = newArray;
refill();
}
overflowCounter = 0;
}
currentBufferId = 0;
}
private void refill() {
for(int i = 0; i < buffers.length; ++i) {
PoolInstance j = fillPoolInstance();
StreamBufferInstance k = buffers[i];
if(j != k.poolInstance) {
PoolInstance l = k.poolInstance;
k.poolInstance = j;
if(k.vertexArray != null) {
if(j.vertexBuffer == null) {
resizeInstance(j, l.vertexBufferSize);
}
initializer.initialize(k.vertexArray, j.vertexBuffer);
}
}
}
}
public void destroy() {
for(int i = 0; i < buffers.length; ++i) {
StreamBufferInstance next = buffers[i];
@ -189,12 +127,6 @@ public class StreamBuffer {
EaglercraftGPU.destroyGLVertexArray(next.vertexArray);
}
}
buffers = new StreamBufferInstance[initialCount];
for(int i = 0; i < initialCount; ++i) {
StreamBufferInstance j = new StreamBufferInstance();
j.poolInstance = fillPoolInstance();
buffers[i] = j;
}
}
public static void destroyPool() {

View File

@ -21,6 +21,7 @@ import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import java.util.List;
import net.lax1dude.eaglercraft.v1_8.Display;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.IProgramGL;
import net.lax1dude.eaglercraft.v1_8.internal.IShaderGL;
@ -100,6 +101,7 @@ public class TextureCopyUtil {
_wglCompileShader(vshShader);
if(_wglGetShaderi(vshShader, GL_COMPILE_STATUS) != GL_TRUE) {
Display.checkContextLost();
LOGGER.error("Failed to compile GL_VERTEX_SHADER \"" + vertexShaderPath + "\" for TextureCopyUtil!");
String log = _wglGetShaderInfoLog(vshShader);
if(log != null) {
@ -126,6 +128,7 @@ public class TextureCopyUtil {
_wglCompileShader(frag);
if(_wglGetShaderi(frag, GL_COMPILE_STATUS) != GL_TRUE) {
Display.checkContextLost();
LOGGER.error("Failed to compile GL_FRAGMENT_SHADER \"" + fragmentShaderPath + "\" for TextureCopyUtil!");
String log = _wglGetShaderInfoLog(frag);
if(log != null) {
@ -154,6 +157,7 @@ public class TextureCopyUtil {
_wglDeleteShader(frag);
if(_wglGetProgrami(shaderProgram, GL_LINK_STATUS) != GL_TRUE) {
Display.checkContextLost();
LOGGER.error("Failed to link shader program for TextureCopyUtil!");
String log = _wglGetProgramInfoLog(shaderProgram);
if(log != null) {

View File

@ -1483,6 +1483,7 @@ public class EaglerDeferredPipeline {
GlStateManager.globalEnableBlend();
GlStateManager.enableBlend();
GlStateManager.depthMask(false);
GlStateManager.cullFace(GL_FRONT);
GlStateManager.tryBlendFuncSeparate(GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_ZERO);
GlStateManager.enablePolygonOffset();
GlStateManager.doPolygonOffset(0.25f, 1.0f);
@ -1497,6 +1498,7 @@ public class EaglerDeferredPipeline {
GlStateManager.disableBlend();
GlStateManager.globalDisableBlend();
GlStateManager.depthMask(true);
GlStateManager.cullFace(GL_BACK);
GlStateManager.disablePolygonOffset();
GlStateManager.colorMask(false, false, false, false);
DeferredStateManager.checkGLError("Post: endDrawColoredShadows()");

View File

@ -92,7 +92,7 @@ public class ForwardAcceleratedEffectRenderer extends AbstractAcceleratedEffectR
_wglVertexAttribDivisor(0, 0);
EaglercraftGPU.bindGLArrayBuffer(instancesBuffer);
_wglBufferData(GL_ARRAY_BUFFER, particleBuffer.remaining(), GL_STREAM_DRAW);
_wglBufferData(GL_ARRAY_BUFFER, particleBuffer.capacity(), GL_STREAM_DRAW);
_wglEnableVertexAttribArray(1);
_wglVertexAttribPointer(1, 3, GL_FLOAT, false, 24, 0);
@ -149,6 +149,7 @@ public class ForwardAcceleratedEffectRenderer extends AbstractAcceleratedEffectR
int l = particleBuffer.limit();
particleBuffer.flip();
_wglBufferData(GL_ARRAY_BUFFER, particleBuffer.capacity(), GL_STREAM_DRAW);
_wglBufferSubData(GL_ARRAY_BUFFER, 0, particleBuffer);
particleBuffer.position(p);

View File

@ -92,7 +92,7 @@ public class GBufferAcceleratedEffectRenderer extends AbstractAcceleratedEffectR
_wglVertexAttribDivisor(0, 0);
EaglercraftGPU.bindGLArrayBuffer(instancesBuffer);
_wglBufferData(GL_ARRAY_BUFFER, particleBuffer.remaining(), GL_STREAM_DRAW);
_wglBufferData(GL_ARRAY_BUFFER, particleBuffer.capacity(), GL_STREAM_DRAW);
_wglEnableVertexAttribArray(1);
_wglVertexAttribPointer(1, 3, GL_FLOAT, false, 24, 0);
@ -148,6 +148,7 @@ public class GBufferAcceleratedEffectRenderer extends AbstractAcceleratedEffectR
int l = particleBuffer.limit();
particleBuffer.flip();
_wglBufferData(GL_ARRAY_BUFFER, particleBuffer.capacity(), GL_STREAM_DRAW);
_wglBufferSubData(GL_ARRAY_BUFFER, 0, particleBuffer);
particleBuffer.position(p);

View File

@ -89,7 +89,7 @@ public class LensFlareMeshRenderer {
streaksVertexArray = _wglGenVertexArrays();
EaglercraftGPU.bindGLVertexArray(streaksVertexArray);
EaglercraftGPU.attachQuad16EmulationBuffer(16, true);
EaglercraftGPU.attachQuad16EmulationBuffer(true);
_wglEnableVertexAttribArray(0);
_wglVertexAttribPointer(0, 2, GL_FLOAT, false, 16, 0);

View File

@ -22,6 +22,7 @@ import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import java.util.Arrays;
import java.util.List;
import net.lax1dude.eaglercraft.v1_8.Display;
import net.lax1dude.eaglercraft.v1_8.internal.IProgramGL;
import net.lax1dude.eaglercraft.v1_8.internal.IShaderGL;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
@ -69,6 +70,7 @@ public class ShaderCompiler {
_wglCompileShader(ret);
if(_wglGetShaderi(ret, GL_COMPILE_STATUS) != GL_TRUE) {
Display.checkContextLost();
logger.error("Failed to compile {} \"{}\" of program \"{}\"!", getStageName(stage), filename, name);
String log = _wglGetShaderInfoLog(ret);
if(log != null) {
@ -95,6 +97,7 @@ public class ShaderCompiler {
_wglDetachShader(ret, frag);
if(_wglGetProgrami(ret, GL_LINK_STATUS) != GL_TRUE) {
Display.checkContextLost();
logger.error("Failed to link program \"{}\"!", name);
String log = _wglGetProgramInfoLog(ret);
if(log != null) {

View File

@ -97,7 +97,7 @@ public class DynamicLightsAcceleratedEffectRenderer extends AbstractAcceleratedE
_wglVertexAttribDivisor(0, 0);
EaglercraftGPU.bindGLArrayBuffer(instancesBuffer);
_wglBufferData(GL_ARRAY_BUFFER, particleBuffer.remaining(), GL_STREAM_DRAW);
_wglBufferData(GL_ARRAY_BUFFER, particleBuffer.capacity(), GL_STREAM_DRAW);
_wglEnableVertexAttribArray(1);
_wglVertexAttribPointer(1, 3, GL_FLOAT, false, 24, 0);
@ -155,6 +155,7 @@ public class DynamicLightsAcceleratedEffectRenderer extends AbstractAcceleratedE
int l = particleBuffer.limit();
particleBuffer.flip();
_wglBufferData(GL_ARRAY_BUFFER, particleBuffer.capacity(), GL_STREAM_DRAW);
_wglBufferSubData(GL_ARRAY_BUFFER, 0, particleBuffer);
particleBuffer.position(p);