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
#Sat Sep 07 08:28:40 EDT 2024
buildNumber=324
#Sun Sep 08 21:41:56 EDT 2024
buildNumber=325

View File

@ -669,6 +669,12 @@ public class Globals {
Globals.server = null;
Globals.serverSynchronizationManager = 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();
}

View File

@ -156,7 +156,7 @@ public class Main {
Globals.controlHandler.hintUpdateControlState(ControlsState.TITLE_MENU);
//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

View File

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

View File

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

View File

@ -65,6 +65,11 @@ public class LoadingThread extends Thread {
*/
LOAD_VIEWPORT,
/**
* Loads initial assets
*/
INIT_ASSETS,
}
/**
@ -152,6 +157,11 @@ public class LoadingThread extends Thread {
case LOAD_VIEWPORT: {
ViewportLoading.loadViewport(params);
} 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 {
//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
long pointer = -1;

View File

@ -111,8 +111,7 @@ public class ThreadManager {
if(thread.getThread().isAlive()){
String errorMessage = "Failed to interrupt thread! " + thread.getLabel();
System.err.println(errorMessage);
new IllegalStateException().printStackTrace();
System.exit(1);
throw new IllegalStateException();
}
} catch (InterruptedException e) {
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;
//the max texture allowed by the current environment
int MAX_TEXTURE_WIDTH = 0;
int MAX_TEXTURE_WIDTH;
//the current viewport dimensions
private Vector2i viewport = new Vector2i(0,0);
private Vector2i viewport;
//whether depth test is enabled or not
boolean depthTest = false;
boolean depthTest;
//the current depth function
int depthFunction = -1;
int depthFunction;
//whether to blend or nit
boolean blendTest = false;
boolean blendTest;
//the current blend func
//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)
static final int ALL_BUFFERS_KEY = -1;
//the currently active texture
int activeTexture = 0;
int activeTexture;
//the currently bound framebuffer
int framebufferType = 0;
int framebufferPointer = 0;
int framebufferType;
int framebufferPointer;
//active shader
ShaderProgram activeShader = null;
ShaderProgram activeShader;
//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)
*/
public void storeCurrentEnvironmentContraints(){
private void storeCurrentEnvironmentContraints(){
//the array used to store values fetched from opengl
int[] intFetchArray = new int[1];
@ -67,6 +85,9 @@ public class OpenGLState {
GL40.glGetIntegerv(GL40.GL_MAX_TEXTURE_SIZE, intFetchArray);
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);
//get environment constraints
openGLState.storeCurrentEnvironmentContraints();
openGLState.init();
//init imgui pipeline
imGuiPipeline = new ImGuiPipeline(Globals.window, glslVersion);
@ -683,7 +683,7 @@ public class RenderingEngine {
public boolean checkError(){
int error = this.getError();
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 false;

View File

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

View File

@ -2,10 +2,15 @@ package electrosphere.test.testutils;
import static org.junit.jupiter.api.Assertions.*;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Assertions;
import java.util.function.Supplier;
import electrosphere.engine.Globals;
import electrosphere.engine.Main;
import electrosphere.engine.loadingthreads.LoadingThread;
import electrosphere.entity.Entity;
/**
@ -87,6 +92,28 @@ public class TestEngineUtils {
* Flushes any signals that haven't been processed yet
*/
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(
Globals.elementService.getSignalQueueCount() > 0
){