fix framebuffer caching bug
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
This commit is contained in:
parent
73a5d79bc2
commit
d8b89aac7d
@ -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
|
||||||
|
|||||||
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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,10 +89,12 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -65,6 +65,11 @@ public class LoadingThread extends Thread {
|
|||||||
*/
|
*/
|
||||||
LOAD_VIEWPORT,
|
LOAD_VIEWPORT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads initial assets
|
||||||
|
*/
|
||||||
|
INIT_ASSETS,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -152,6 +157,11 @@ public class LoadingThread extends Thread {
|
|||||||
case LOAD_VIEWPORT: {
|
case LOAD_VIEWPORT: {
|
||||||
ViewportLoading.loadViewport(params);
|
ViewportLoading.loadViewport(params);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
//Load the initial assets
|
||||||
|
case INIT_ASSETS: {
|
||||||
|
InitialAssetLoading.loadData();
|
||||||
|
} break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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");
|
||||||
|
|||||||
@ -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];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
){
|
){
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user