Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for multiple owo-ui windows #161

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.wispforest.owo.mixin;

import io.wispforest.owo.ui.window.OpenWindows;
import io.wispforest.owo.util.OwoFreezer;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.RunArgs;
Expand Down Expand Up @@ -28,5 +29,9 @@ private void afterQuiltHook(RunArgs args, CallbackInfo ci) {
OwoFreezer.freeze();
}

@Inject(method = "render", at = @At(value = "INVOKE_STRING", args = "ldc=yield", target = "Lnet/minecraft/util/profiler/Profiler;swap(Ljava/lang/String;)V"))
private void renderAllWindows(CallbackInfo ci) {
OpenWindows.renderAll();
}
}

10 changes: 10 additions & 0 deletions src/main/java/io/wispforest/owo/mixin/ui/ScreenMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import io.wispforest.owo.ui.base.BaseOwoHandledScreen;
import io.wispforest.owo.ui.base.BaseOwoScreen;
import io.wispforest.owo.ui.core.OwoUIDrawContext;
import io.wispforest.owo.ui.window.context.CurrentWindowContext;
import io.wispforest.owo.ui.window.context.VanillaWindowContext;
import io.wispforest.owo.ui.window.context.WindowContext;
import net.minecraft.client.gui.screen.Screen;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
Expand All @@ -30,4 +33,11 @@ private boolean dontCloseOwoScreens(boolean original) {
if ((Object) this != OwoUIDrawContext.utilityScreen()) return screen;
return OwoUIDrawContext.utilityScreen().getAndClearLinkSource();
}

@ModifyArg(method = {"hasShiftDown", "hasControlDown", "hasAltDown"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/InputUtil;isKeyPressed(JI)Z"), index = 0)
private static long replaceOnOtherWindow(long handle) {
WindowContext ctx = CurrentWindowContext.current();

return ctx != VanillaWindowContext.MAIN ? ctx.handle() : handle;
}
}
38 changes: 26 additions & 12 deletions src/main/java/io/wispforest/owo/shader/BlurProgram.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package io.wispforest.owo.shader;

import io.wispforest.owo.ui.core.Surface;
import io.wispforest.owo.ui.event.WindowResizeCallback;
import io.wispforest.owo.ui.window.context.CurrentWindowContext;
import io.wispforest.owo.ui.window.context.WindowContext;
import io.wispforest.owo.util.SupportsFeatures;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gl.Framebuffer;
import net.minecraft.client.gl.GlUniform;
Expand All @@ -21,15 +23,9 @@ public class BlurProgram extends GlProgram {
private GlUniform directions;
private GlUniform quality;
private GlUniform size;
private Framebuffer input;

public BlurProgram() {
super(Identifier.of("owo", "blur"), VertexFormats.POSITION);

WindowResizeCallback.EVENT.register((client, window) -> {
if (this.input == null) return;
this.input.resize(window.getFramebufferWidth(), window.getFramebufferHeight(), MinecraftClient.IS_SYSTEM_MAC);
});
}

public void setParameters(int directions, float quality, float size) {
Expand All @@ -40,15 +36,17 @@ public void setParameters(int directions, float quality, float size) {

@Override
public void use() {
var buffer = MinecraftClient.getInstance().getFramebuffer();
var window = CurrentWindowContext.current();
var buffer = window.framebuffer();
var input = window.get(BlurInputFeature.KEY).input;

this.input.beginWrite(false);
input.beginWrite(false);
GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, buffer.fbo);
GL30.glBlitFramebuffer(0, 0, buffer.textureWidth, buffer.textureHeight, 0, 0, buffer.textureWidth, buffer.textureHeight, GL30.GL_COLOR_BUFFER_BIT, GL30.GL_LINEAR);
buffer.beginWrite(false);

this.inputResolution.set((float) buffer.textureWidth, (float) buffer.textureHeight);
this.backingProgram.addSampler("InputSampler", this.input.getColorAttachment());
this.backingProgram.addSampler("InputSampler", input.getColorAttachment());

super.use();
}
Expand All @@ -59,8 +57,24 @@ protected void setup() {
this.directions = this.findUniform("Directions");
this.quality = this.findUniform("Quality");
this.size = this.findUniform("Size");
}

private static final class BlurInputFeature implements AutoCloseable {
private static final SupportsFeatures.Key<WindowContext, BlurInputFeature> KEY = new SupportsFeatures.Key<>(BlurInputFeature::new);

private final Framebuffer input;

public BlurInputFeature(WindowContext ctx) {
this.input = new SimpleFramebuffer(ctx.framebufferWidth(), ctx.framebufferHeight(), false, MinecraftClient.IS_SYSTEM_MAC);

ctx.framebufferResized().subscribe((newWidth, newHeight) -> {
this.input.resize(newWidth, newHeight, MinecraftClient.IS_SYSTEM_MAC);
});
}

var window = MinecraftClient.getInstance().getWindow();
this.input = new SimpleFramebuffer(window.getFramebufferWidth(), window.getFramebufferHeight(), false, MinecraftClient.IS_SYSTEM_MAC);
@Override
public void close() {
this.input.delete();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
import io.wispforest.owo.ui.core.Component;
import io.wispforest.owo.ui.core.OwoUIDrawContext;
import io.wispforest.owo.ui.core.Sizing;
import io.wispforest.owo.ui.event.WindowResizeCallback;
import io.wispforest.owo.ui.util.ScissorStack;
import io.wispforest.owo.ui.window.context.CurrentWindowContext;
import io.wispforest.owo.ui.window.context.WindowContext;
import io.wispforest.owo.util.SupportsFeatures;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gl.Framebuffer;
import net.minecraft.client.gl.SimpleFramebuffer;
Expand All @@ -24,6 +26,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;

/**
Expand All @@ -41,7 +44,6 @@
@ApiStatus.Experimental
public class RenderEffectWrapper<C extends Component> extends WrappingParentComponent<C> {

protected static final List<Framebuffer> FRAMEBUFFERS = new ArrayList<>();
protected static int drawDepth = 0;

protected final List<RenderEffectSlot> effects = new ArrayList<>();
Expand All @@ -58,13 +60,11 @@ public void draw(OwoUIDrawContext context, int mouseX, int mouseY, float partial
try {
drawDepth++;

var window = MinecraftClient.getInstance().getWindow();
while (drawDepth > FRAMEBUFFERS.size()) {
FRAMEBUFFERS.add(new SimpleFramebuffer(window.getFramebufferWidth(), window.getFramebufferHeight(), true, MinecraftClient.IS_SYSTEM_MAC));
}
var window = CurrentWindowContext.current();
var feature = window.get(FramebuffersFeature.KEY);

var previousFramebuffer = GlStateManager.getBoundFramebuffer();
var framebuffer = FRAMEBUFFERS.get(drawDepth - 1);
var framebuffer = feature.getFor(drawDepth);
framebuffer.setClearColor(0, 0, 0, 0);
ScissorStack.drawUnclipped(() -> framebuffer.clear(MinecraftClient.IS_SYSTEM_MAC));
framebuffer.beginWrite(false);
Expand All @@ -81,9 +81,9 @@ public void draw(OwoUIDrawContext context, int mouseX, int mouseY, float partial
var buffer = RenderSystem.renderThreadTesselator().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
var matrix = context.getMatrices().peek().getPositionMatrix();

buffer.vertex(matrix, 0, window.getScaledHeight(), 0).texture(0, 0).color(1f, 1f, 1f, 1f);
buffer.vertex(matrix, window.getScaledWidth(), window.getScaledHeight(), 0).texture(1, 0).color(1f, 1f, 1f, 1f);
buffer.vertex(matrix, window.getScaledWidth(), 0, 0).texture(1, 1).color(1f, 1f, 1f, 1f);
buffer.vertex(matrix, 0, window.scaledHeight(), 0).texture(0, 0).color(1f, 1f, 1f, 1f);
buffer.vertex(matrix, window.scaledWidth(), window.scaledHeight(), 0).texture(1, 0).color(1f, 1f, 1f, 1f);
buffer.vertex(matrix, window.scaledWidth(), 0, 0).texture(1, 1).color(1f, 1f, 1f, 1f);
buffer.vertex(matrix, 0, 0, 0).texture(0, 1).color(1f, 1f, 1f, 1f);

RenderSystem.setShaderTexture(0, framebuffer.getColorAttachment());
Expand Down Expand Up @@ -121,12 +121,37 @@ public void clearEffects() {
this.effects.clear();
}

static {
WindowResizeCallback.EVENT.register((client, window) -> {
FRAMEBUFFERS.forEach(framebuffer -> {
framebuffer.resize(window.getFramebufferWidth(), window.getFramebufferHeight(), MinecraftClient.IS_SYSTEM_MAC);
private static final class FramebuffersFeature implements AutoCloseable {
private static final SupportsFeatures.Key<WindowContext, FramebuffersFeature> KEY = new SupportsFeatures.Key<>(FramebuffersFeature::new);

private final WindowContext ctx;
private final List<Framebuffer> framebuffers;

public FramebuffersFeature(WindowContext ctx) {
this.framebuffers = new ArrayList<>();
this.ctx = ctx;

ctx.framebufferResized().subscribe((newWidth, newHeight) -> {
framebuffers.forEach(framebuffer -> {
framebuffer.resize(newWidth, newHeight, MinecraftClient.IS_SYSTEM_MAC);
});
});
});
}

public Framebuffer getFor(int drawDepth) {
while (drawDepth > framebuffers.size()) {
framebuffers.add(new SimpleFramebuffer(ctx.framebufferWidth(), ctx.framebufferHeight(), true, MinecraftClient.IS_SYSTEM_MAC));
}

return framebuffers.get(drawDepth - 1);
}

@Override
public void close() {
for (Framebuffer fb : framebuffers) {
fb.delete();
}
}
}

public class RenderEffectSlot {
Expand Down
19 changes: 18 additions & 1 deletion src/main/java/io/wispforest/owo/ui/core/OwoUIAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import io.wispforest.owo.Owo;
import io.wispforest.owo.renderdoc.RenderDoc;
import io.wispforest.owo.ui.util.CursorAdapter;
import io.wispforest.owo.ui.window.context.CurrentWindowContext;
import io.wispforest.owo.ui.window.OwoWindow;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.Drawable;
Expand Down Expand Up @@ -56,6 +58,16 @@ protected OwoUIAdapter(int x, int y, int width, int height, R rootComponent) {
this.rootComponent = rootComponent;
}

protected OwoUIAdapter(int x, int y, int width, int height, R rootComponent, OwoWindow<?> window) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;

this.cursorAdapter = CursorAdapter.ofWindow(window.handle());
this.rootComponent = rootComponent;
}

/**
* Create a UI adapter for the given screen. This also sets it up
* to be rendered and receive input events, without needing you to
Expand Down Expand Up @@ -93,6 +105,11 @@ public static <R extends ParentComponent> OwoUIAdapter<R> createWithoutScreen(in
return new OwoUIAdapter<>(x, y, width, height, rootComponent);
}

public static <R extends ParentComponent> OwoUIAdapter<R> create(OwoWindow<?> window, BiFunction<Sizing, Sizing, R> rootComponentMaker) {
var rootComponent = rootComponentMaker.apply(Sizing.fill(100), Sizing.fill(100));
return new OwoUIAdapter<>(0, 0, window.scaledWidth(), window.scaledHeight(), rootComponent, window);
}

/**
* Begin the layout process of the UI tree and
* mount the tree once the layout is inflated
Expand Down Expand Up @@ -174,7 +191,7 @@ public void render(DrawContext context, int mouseX, int mouseY, float partialTic
RenderSystem.enableDepthTest();
GlStateManager._enableScissorTest();

GlStateManager._scissorBox(0, 0, window.getFramebufferWidth(), window.getFramebufferHeight());
GlStateManager._scissorBox(0, 0, CurrentWindowContext.current().framebufferWidth(), CurrentWindowContext.current().framebufferHeight());
this.rootComponent.draw(owoContext, mouseX, mouseY, partialTicks, delta);

GlStateManager._disableScissorTest();
Expand Down
34 changes: 12 additions & 22 deletions src/main/java/io/wispforest/owo/ui/core/OwoUIDrawContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import com.mojang.blaze3d.systems.RenderSystem;
import io.wispforest.owo.client.OwoClient;
import io.wispforest.owo.mixin.ui.DrawContextInvoker;
import io.wispforest.owo.ui.event.WindowResizeCallback;
import io.wispforest.owo.ui.util.NinePatchTexture;
import io.wispforest.owo.ui.window.context.CurrentWindowContext;
import io.wispforest.owo.ui.window.context.WindowContext;
import io.wispforest.owo.util.SupportsFeatures;
import io.wispforest.owo.util.pond.OwoTessellatorExtension;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
Expand Down Expand Up @@ -348,27 +350,22 @@ public void drawInspector(ParentComponent root, double mouseX, double mouseY, bo

public static class UtilityScreen extends Screen {

private static UtilityScreen INSTANCE;
private static final SupportsFeatures.Key<WindowContext, UtilityScreen> KEY = new SupportsFeatures.Key<>(UtilityScreen::new);

private Screen linkSourceScreen = null;

private UtilityScreen() {
private UtilityScreen(WindowContext ctx) {
super(Text.empty());

this.init(MinecraftClient.getInstance(), ctx.scaledWidth(), ctx.scaledHeight());

ctx.framebufferResized().subscribe((newWidth, newHeight) -> {
this.init(MinecraftClient.getInstance(), ctx.scaledWidth(), ctx.scaledHeight());
});
}

public static UtilityScreen get() {
if (INSTANCE == null) {
INSTANCE = new UtilityScreen();

final var client = MinecraftClient.getInstance();
INSTANCE.init(
client,
client.getWindow().getScaledWidth(),
client.getWindow().getScaledHeight()
);
}

return INSTANCE;
return CurrentWindowContext.current().get(KEY);
}

/**
Expand Down Expand Up @@ -406,12 +403,5 @@ public void captureLinkSource() {
public boolean handleTextClick(@Nullable Style style) {
return super.handleTextClick(style);
}

static {
WindowResizeCallback.EVENT.register((client, window) -> {
if (INSTANCE == null) return;
INSTANCE.init(client, window.getScaledWidth(), window.getScaledHeight());
});
}
}
}
31 changes: 31 additions & 0 deletions src/main/java/io/wispforest/owo/ui/util/OwoGlUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package io.wispforest.owo.ui.util;

import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.systems.VertexSorter;
import io.wispforest.owo.util.InfallibleCloseable;
import org.joml.Matrix4f;
import org.lwjgl.glfw.GLFW;

public final class OwoGlUtil {
private OwoGlUtil() {

}

public static InfallibleCloseable setContext(long handle) {
long old = GLFW.glfwGetCurrentContext();
if (old == handle) return InfallibleCloseable.empty();

GLFW.glfwMakeContextCurrent(handle);

return () -> GLFW.glfwMakeContextCurrent(old);
}

public static InfallibleCloseable setProjectionMatrix(Matrix4f projectionMatrix, VertexSorter sorter) {
Matrix4f oldMatrix = RenderSystem.getProjectionMatrix();
VertexSorter oldSorter = RenderSystem.getVertexSorting();

RenderSystem.setProjectionMatrix(projectionMatrix, sorter);

return () -> RenderSystem.setProjectionMatrix(oldMatrix, oldSorter);
}
}
Loading
Loading