fix framebuffer caching bug
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-09-09 12:42:29 -04:00
parent 73a5d79bc2
commit d8b89aac7d
14 changed files with 139 additions and 66 deletions

View File

@ -1,3 +1,3 @@
#maven.buildNumber.plugin properties file #maven.buildNumber.plugin properties file
#Sat Sep 07 08:28:40 EDT 2024 #Sun Sep 08 21:41:56 EDT 2024
buildNumber=324 buildNumber=325

View File

@ -669,6 +669,12 @@ public class Globals {
Globals.server = null; Globals.server = null;
Globals.serverSynchronizationManager = null; Globals.serverSynchronizationManager = null;
Globals.javaPID = null; Globals.javaPID = null;
Globals.RENDER_FLAG_RENDER_SHADOW_MAP = true;
Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT = false;
Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER = false;
Globals.RENDER_FLAG_RENDER_UI = false;
Globals.RENDER_FLAG_RENDER_BLACK_BACKGROUND = false;
Globals.RENDER_FLAG_RENDER_WHITE_BACKGROUND = false;
LoggerInterface.destroyLoggers(); LoggerInterface.destroyLoggers();
} }

View File

@ -156,7 +156,7 @@ public class Main {
Globals.controlHandler.hintUpdateControlState(ControlsState.TITLE_MENU); Globals.controlHandler.hintUpdateControlState(ControlsState.TITLE_MENU);
//start initial asset loading //start initial asset loading
Globals.threadManager.start(ThreadLabel.ASSET_LOADING, new Thread(Globals.initialAssetLoadingThread)); Globals.threadManager.start(new LoadingThread(LoadingThreadType.INIT_ASSETS));
} }
//Sets a hook that fires when the engine process stops //Sets a hook that fires when the engine process stops

View File

@ -258,7 +258,7 @@ public class ClientLoading {
*/ */
static void initDrawCellManager(boolean blockForInit){ static void initDrawCellManager(boolean blockForInit){
int iterations = 0; int iterations = 0;
while(blockForInit && (Globals.clientWorldData == null || Globals.initialAssetLoadingThread.isLoading())){ while(blockForInit && (Globals.clientWorldData == null || InitialAssetLoading.atlasQueuedTexture == null || !InitialAssetLoading.atlasQueuedTexture.hasLoaded())){
try { try {
TimeUnit.MILLISECONDS.sleep(10); TimeUnit.MILLISECONDS.sleep(10);
iterations++; iterations++;
@ -268,7 +268,7 @@ public class ClientLoading {
if(iterations > MAX_DRAW_CELL_WAIT){ if(iterations > MAX_DRAW_CELL_WAIT){
String message = "Draw cell took too long to init!\n" + String message = "Draw cell took too long to init!\n" +
Globals.clientWorldData + "\n" + Globals.clientWorldData + "\n" +
Globals.initialAssetLoadingThread.isLoading(); InitialAssetLoading.atlasQueuedTexture.hasLoaded();
throw new IllegalStateException(message); throw new IllegalStateException(message);
} }
} }

View File

@ -21,35 +21,27 @@ import electrosphere.util.FileUtils;
* - Texture Atlas for terrain * - Texture Atlas for terrain
* - Icons for items * - Icons for items
*/ */
public class InitialAssetLoading implements Runnable { public class InitialAssetLoading {
//tracks whether this thread is still doing work or not /**
boolean loading = true; * The queued atlas texture
*/
static QueuedTexture atlasQueuedTexture = null;
/** /**
* Loads basic data * Loads basic data
*/ */
public void LoadData(){ protected static void loadData(){
loadTextureAtlas(); loadTextureAtlas();
LoggerInterface.loggerEngine.INFO("Finished loading texture atlas"); LoggerInterface.loggerEngine.INFO("Finished loading texture atlas");
loading = false;
}
/**
* Gets whether the thread is still loading or not
* @return true if loading, false otherwise
*/
public boolean isLoading(){
return loading;
} }
/** /**
* Loads the texture atlas * Loads the texture atlas
*/ */
private void loadTextureAtlas(){ private static void loadTextureAtlas(){
//terrain texture atlas //terrain texture atlas
Globals.profiler.beginCpuSample("createVoxelTextureAtlas"); Globals.profiler.beginCpuSample("createVoxelTextureAtlas");
VoxelData data = Globals.gameConfigCurrent.getVoxelData(); VoxelData data = Globals.gameConfigCurrent.getVoxelData();
@ -78,7 +70,7 @@ public class InitialAssetLoading implements Runnable {
Globals.profiler.endCpuSample(); Globals.profiler.endCpuSample();
//queue to asset manager //queue to asset manager
QueuedTexture atlasQueuedTexture = new QueuedTexture(image); atlasQueuedTexture = new QueuedTexture(image);
Globals.assetManager.queuedAsset(atlasQueuedTexture); Globals.assetManager.queuedAsset(atlasQueuedTexture);
@ -97,9 +89,11 @@ public class InitialAssetLoading implements Runnable {
Globals.voxelTextureAtlas.setNormal(atlasQueuedTexture.getTexture()); Globals.voxelTextureAtlas.setNormal(atlasQueuedTexture.getTexture());
} }
@Override /**
public void run(){ * Gets the queued texture
this.LoadData(); */
protected static QueuedTexture getQueuedTexture(){
return atlasQueuedTexture;
} }

View File

@ -65,6 +65,11 @@ public class LoadingThread extends Thread {
*/ */
LOAD_VIEWPORT, LOAD_VIEWPORT,
/**
* Loads initial assets
*/
INIT_ASSETS,
} }
/** /**
@ -153,6 +158,11 @@ public class LoadingThread extends Thread {
ViewportLoading.loadViewport(params); ViewportLoading.loadViewport(params);
} break; } break;
//Load the initial assets
case INIT_ASSETS: {
InitialAssetLoading.loadData();
} break;
} }
} }

View File

@ -10,7 +10,8 @@ import org.lwjgl.util.remotery.Remotery;
public class Profiler { public class Profiler {
//controls whether to profile or not //controls whether to profile or not
public static boolean PROFILE = true; //!!WARNING!!: when this is turned on, testing can behave weirdly!! IE GET STUCK!
public static boolean PROFILE = false;
//pointer to the global instance //pointer to the global instance
long pointer = -1; long pointer = -1;

View File

@ -111,8 +111,7 @@ public class ThreadManager {
if(thread.getThread().isAlive()){ if(thread.getThread().isAlive()){
String errorMessage = "Failed to interrupt thread! " + thread.getLabel(); String errorMessage = "Failed to interrupt thread! " + thread.getLabel();
System.err.println(errorMessage); System.err.println(errorMessage);
new IllegalStateException().printStackTrace(); throw new IllegalStateException();
System.exit(1);
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
CodeUtils.todo(e, "Think about how to handle this"); CodeUtils.todo(e, "Think about how to handle this");

View File

@ -21,44 +21,62 @@ public class OpenGLState {
private static final boolean DISABLE_CACHING = false; private static final boolean DISABLE_CACHING = false;
//the max texture allowed by the current environment //the max texture allowed by the current environment
int MAX_TEXTURE_WIDTH = 0; int MAX_TEXTURE_WIDTH;
//the current viewport dimensions //the current viewport dimensions
private Vector2i viewport = new Vector2i(0,0); private Vector2i viewport;
//whether depth test is enabled or not //whether depth test is enabled or not
boolean depthTest = false; boolean depthTest;
//the current depth function //the current depth function
int depthFunction = -1; int depthFunction;
//whether to blend or nit //whether to blend or nit
boolean blendTest = false; boolean blendTest;
//the current blend func //the current blend func
//map is (texture unit) -> [sfactor,dfactor] //map is (texture unit) -> [sfactor,dfactor]
Map<Integer,int[]> blendFuncMap = new HashMap<Integer,int[]>(); Map<Integer,int[]> blendFuncMap;
//the key that contains the value of glBlendFunc (which would affect all buffers) //the key that contains the value of glBlendFunc (which would affect all buffers)
static final int ALL_BUFFERS_KEY = -1; static final int ALL_BUFFERS_KEY = -1;
//the currently active texture //the currently active texture
int activeTexture = 0; int activeTexture;
//the currently bound framebuffer //the currently bound framebuffer
int framebufferType = 0; int framebufferType;
int framebufferPointer = 0; int framebufferPointer;
//active shader //active shader
ShaderProgram activeShader = null; ShaderProgram activeShader;
//map of texture units and their corresponding texture pointers //map of texture units and their corresponding texture pointers
Map<Integer,Integer> unitToPointerMap = new HashMap<Integer,Integer>(); Map<Integer,Integer> unitToPointerMap;
/**
* Initializes the opengl state
*/
public void init(){
this.MAX_TEXTURE_WIDTH = 0;
this.viewport = new Vector2i(0,0);
this.depthTest = false;
this.depthFunction = -1;
this.blendTest = false;
this.blendFuncMap = new HashMap<Integer,int[]>();
activeTexture = 0;
framebufferType = 0;
framebufferPointer = 0;
activeShader = null;
unitToPointerMap = new HashMap<Integer,Integer>();
this.storeCurrentEnvironmentContraints();
}
/** /**
* Gets the constraints of the current environment (ie how large can the max texture be) * Gets the constraints of the current environment (ie how large can the max texture be)
*/ */
public void storeCurrentEnvironmentContraints(){ private void storeCurrentEnvironmentContraints(){
//the array used to store values fetched from opengl //the array used to store values fetched from opengl
int[] intFetchArray = new int[1]; int[] intFetchArray = new int[1];
@ -67,6 +85,9 @@ public class OpenGLState {
GL40.glGetIntegerv(GL40.GL_MAX_TEXTURE_SIZE, intFetchArray); GL40.glGetIntegerv(GL40.GL_MAX_TEXTURE_SIZE, intFetchArray);
MAX_TEXTURE_WIDTH = intFetchArray[0]; MAX_TEXTURE_WIDTH = intFetchArray[0];
//get current framebuffer data
GL40.glGetIntegerv(GL40.GL_DRAW_FRAMEBUFFER_BINDING, intFetchArray);
this.framebufferPointer = intFetchArray[0];
} }

View File

@ -283,7 +283,7 @@ public class RenderingEngine {
}, bufferHeight); }, bufferHeight);
//get environment constraints //get environment constraints
openGLState.storeCurrentEnvironmentContraints(); openGLState.init();
//init imgui pipeline //init imgui pipeline
imGuiPipeline = new ImGuiPipeline(Globals.window, glslVersion); imGuiPipeline = new ImGuiPipeline(Globals.window, glslVersion);
@ -683,7 +683,7 @@ public class RenderingEngine {
public boolean checkError(){ public boolean checkError(){
int error = this.getError(); int error = this.getError();
if(error != GL11.GL_NO_ERROR){ if(error != GL11.GL_NO_ERROR){
LoggerInterface.loggerRenderer.ERROR("checkError - " + getErrorInEnglish(error), new IllegalStateException("OpenGL Error")); LoggerInterface.loggerRenderer.ERROR("checkError - " + getErrorInEnglish(error), new Exception("OpenGL Error"));
return true; return true;
} }
return false; return false;

View File

@ -111,7 +111,6 @@ public class FramebufferUtils {
buffer.attachTexture(openGLState,colorTexture); buffer.attachTexture(openGLState,colorTexture);
buffer.setDepthAttachment(openGLState,depthTexture); buffer.setDepthAttachment(openGLState,depthTexture);
buffer.bind(openGLState); buffer.bind(openGLState);
Globals.renderingEngine.defaultFramebuffer.bind(openGLState);
//check make sure compiled //check make sure compiled
buffer.shouldBeComplete(openGLState); buffer.shouldBeComplete(openGLState);
Globals.renderingEngine.defaultFramebuffer.bind(openGLState); Globals.renderingEngine.defaultFramebuffer.bind(openGLState);

View File

@ -0,0 +1,38 @@
package electrosphere.engine;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import org.junit.jupiter.api.extension.ExtendWith;
import electrosphere.test.annotations.IntegrationTest;
import electrosphere.test.template.extensions.EntityExtension;
import electrosphere.test.template.extensions.StateCleanupCheckerExtension;
/**
* Tests for startup extensions
*/
@ExtendWith(StateCleanupCheckerExtension.class)
public class StartupExtensionTests {
@IntegrationTest
public void test_EntityExtension_Startup(){
assertDoesNotThrow(() -> {
EntityExtension ext = new EntityExtension();
ext.beforeEach(null);
ext.afterEach(null);
});
}
@IntegrationTest
public void test_EntityExtension_RepeatStartup(){
assertDoesNotThrow(() -> {
EntityExtension ext = new EntityExtension();
int someNumberOfTests = 3;
for(int i = 0; i < someNumberOfTests; i++){
ext.beforeEach(null);
ext.afterEach(null);
}
});
}
}

View File

@ -83,28 +83,6 @@ public class EngineInit {
LoadingThread loadingThread = new LoadingThread(LoadingThreadType.LOAD_VIEWPORT); LoadingThread loadingThread = new LoadingThread(LoadingThreadType.LOAD_VIEWPORT);
Globals.threadManager.start(loadingThread); Globals.threadManager.start(loadingThread);
//
//wait for client to be fully init'd
int frames = 0;
while(Globals.threadManager.isLoading()){
TestEngineUtils.simulateFrames(1);
try {
TimeUnit.MILLISECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
frames++;
if(frames > MAX_FRAMES_TO_WAIT){
String errorMessage = "Failed to setup connected test scene!\n" +
"Still running threads are:\n"
;
for(LoadingThread thread : Globals.threadManager.getLoadingThreads()){
errorMessage = errorMessage + thread.getType() + "\n";
}
Assertions.fail("Failed to startup");
}
}
TestEngineUtils.flush(); TestEngineUtils.flush();
} }

View File

@ -2,10 +2,15 @@ package electrosphere.test.testutils;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Assertions;
import java.util.function.Supplier; import java.util.function.Supplier;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.engine.Main; import electrosphere.engine.Main;
import electrosphere.engine.loadingthreads.LoadingThread;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
/** /**
@ -87,6 +92,28 @@ public class TestEngineUtils {
* Flushes any signals that haven't been processed yet * Flushes any signals that haven't been processed yet
*/ */
public static void flush(){ public static void flush(){
//
//wait for client to be fully init'd
int frames = 0;
while(Globals.threadManager.isLoading()){
TestEngineUtils.simulateFrames(1);
try {
TimeUnit.MILLISECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
frames++;
if(frames > EngineInit.MAX_FRAMES_TO_WAIT){
String errorMessage = "Failed to setup connected test scene!\n" +
"Still running threads are:\n"
;
for(LoadingThread thread : Globals.threadManager.getLoadingThreads()){
errorMessage = errorMessage + thread.getType() + "\n";
}
Assertions.fail("Failed to startup");
}
}
while( while(
Globals.elementService.getSignalQueueCount() > 0 Globals.elementService.getSignalQueueCount() > 0
){ ){