Skip to content

Commit

Permalink
Added state tracking for OpenGL to leave the GL state untouched when …
Browse files Browse the repository at this point in the history
…rendering EarlyDisplay
  • Loading branch information
shartte committed Mar 2, 2025
1 parent f496f9e commit ad781ea
Show file tree
Hide file tree
Showing 8 changed files with 464 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -174,14 +174,14 @@ private void renderThreadFunc() {
nextFrameTime = nt + MINFRAMETIME;
glfwMakeContextCurrent(window);
framebuffer.activate();
glViewport(0, 0, this.context.scaledWidth(), this.context.scaledHeight());
GlState.viewport(0, 0, this.context.scaledWidth(), this.context.scaledHeight());
this.context.elementShader().activate();
this.context.elementShader().updateScreenSizeUniform(this.context.scaledWidth(), this.context.scaledHeight());
glClearColor(colourScheme.background().redf(), colourScheme.background().greenf(), colourScheme.background().bluef(), 1f);
GlState.clearColor(colourScheme.background().redf(), colourScheme.background().greenf(), colourScheme.background().bluef(), 1f);
paintFramebuffer();
this.context.elementShader().clear();
framebuffer.deactivate();
glViewport(0, 0, fbWidth, fbHeight);
GlState.viewport(0, 0, fbWidth, fbHeight);
framebuffer.draw(this.fbWidth, this.fbHeight);
// Swap buffers; we're done
glfwSwapBuffers(window);
Expand Down Expand Up @@ -216,7 +216,7 @@ private void initRender(final @Nullable String mcVersion, final String forgeVers
}

// Set the clear color based on the colour scheme
glClearColor(colourScheme.background().redf(), colourScheme.background().greenf(), colourScheme.background().bluef(), 1f);
GlState.clearColor(colourScheme.background().redf(), colourScheme.background().greenf(), colourScheme.background().bluef(), 1f);

// we always render to an 854x480 texture and then fit that to the screen - with a scale factor
this.context = new RenderElement.DisplayContext(854, 480, fbScale, elementShader, colourScheme, performanceInfo);
Expand All @@ -238,8 +238,8 @@ private void initRender(final @Nullable String mcVersion, final String forgeVers
if (FMLConfig.getBoolConfigValue(FMLConfig.ConfigValue.EARLY_WINDOW_SQUIR) || (date.get(Calendar.MONTH) == Calendar.APRIL && date.get(Calendar.DAY_OF_MONTH) == 1))
this.elements.add(0, RenderElement.squir());

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GlState.enableBlend(true);
GlState.blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glfwMakeContextCurrent(0);
this.windowTick = renderScheduler.scheduleAtFixedRate(this::renderThreadFunc, 50, 50, TimeUnit.MILLISECONDS);
this.performanceTick = renderScheduler.scheduleAtFixedRate(performanceInfo::update, 0, 500, TimeUnit.MILLISECONDS);
Expand All @@ -253,8 +253,8 @@ private void initRender(final @Nullable String mcVersion, final String forgeVers
void paintFramebuffer() {
// Clear the screen to our color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GlState.enableBlend(true);
GlState.blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

this.elements.removeIf(element -> !element.render(context, framecount));
if (animationTimerTrigger.compareAndSet(true, false)) // we only increment the framecount on a periodic basis
Expand All @@ -265,16 +265,20 @@ public void render(int alpha) {
var currentVAO = glGetInteger(GL_VERTEX_ARRAY_BINDING);
var currentFB = glGetInteger(GL_READ_FRAMEBUFFER_BINDING);
glViewport(0, 0, this.context.scaledWidth(), this.context.scaledHeight());
GlState.readFromOpenGL();
var backup = GlState.createSnapshot();

GlState.viewport(0, 0, this.context.scaledWidth(), this.context.scaledHeight());
RenderElement.globalAlpha = alpha;
framebuffer.activate();
glClearColor(colourScheme.background().redf(), colourScheme.background().greenf(), colourScheme.background().bluef(), alpha / 255f);
GlState.clearColor(colourScheme.background().redf(), colourScheme.background().greenf(), colourScheme.background().bluef(), alpha / 255f);
elementShader.activate();
elementShader.updateScreenSizeUniform(this.context.scaledWidth(), this.context.scaledHeight());
paintFramebuffer();
elementShader.clear();
framebuffer.deactivate();
glBindVertexArray(currentVAO);
glBindFramebuffer(GL_FRAMEBUFFER, currentFB);

GlState.applySnapshot(backup);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,22 @@ public class EarlyFramebuffer {
this.context = context;
this.framebuffer = glGenFramebuffers();
this.texture = glGenTextures();
glBindFramebuffer(GL_FRAMEBUFFER, this.framebuffer);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, this.texture);
GlState.bindFramebuffer(this.framebuffer);
GlState.activeTexture(GL_TEXTURE0);
GlState.bindTexture2D(this.texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, context.width() * context.scale(), context.height() * context.scale(), 0, GL_RGBA, GL_UNSIGNED_BYTE, (IntBuffer) null);
glTexParameterIi(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterIi(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this.texture, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
GlState.bindFramebuffer(0);
}

void activate() {
glBindFramebuffer(GL_FRAMEBUFFER, this.framebuffer);
GlState.bindFramebuffer(this.framebuffer);
}

void deactivate() {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
GlState.bindFramebuffer(0);
}

void draw(int windowFBWidth, int windowFBHeight) {
Expand All @@ -45,14 +45,14 @@ void draw(int windowFBWidth, int windowFBHeight) {
var wtop = (int) (windowFBHeight * 0.5f - scale * this.context.height());
var wright = (int) (windowFBWidth * 0.5f + scale * this.context.width());
var wbottom = (int) (windowFBHeight * 0.5f + scale * this.context.height());
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, this.framebuffer);
GlState.bindDrawFramebuffer(0);
GlState.bindReadFramebuffer(this.framebuffer);
final var colour = this.context.colourScheme().background();
glClearColor(colour.redf(), colour.greenf(), colour.bluef(), 1f);
GlState.clearColor(colour.redf(), colour.greenf(), colour.bluef(), 1f);
glClear(GL_COLOR_BUFFER_BIT);
// src Y are flipped, since our FB is flipped
glBlitFramebuffer(0, this.context.height() * this.context.scale(), this.context.width() * this.context.scale(), 0, RenderElement.clamp(wleft, 0, windowFBWidth), RenderElement.clamp(wtop, 0, windowFBHeight), RenderElement.clamp(wright, 0, windowFBWidth), RenderElement.clamp(wbottom, 0, windowFBHeight), GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
GlState.bindFramebuffer(0);
}

int getTexture() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ void main() {
}

public void activate() {
glUseProgram(program);
GlState.useProgram(program);
}

public void updateTextureUniform(int textureNumber) {
Expand All @@ -100,7 +100,7 @@ public void updateRenderTypeUniform(RenderType type) {
}

public void clear() {
glUseProgram(0);
GlState.useProgram(0);
}

public void close() {
Expand Down
Loading

0 comments on commit ad781ea

Please sign in to comment.