Skip to content

Commit

Permalink
config: framebuffer scaling
Browse files Browse the repository at this point in the history
This option allows setting a different resolution for the world or gui framebuffer than the actual screen has. This can improve performance if you don't need as much quality and the whole game is fragment shader bottlenecked
  • Loading branch information
Bixilon committed May 10, 2024
1 parent ae7a289 commit 91c0e2b
Show file tree
Hide file tree
Showing 14 changed files with 122 additions and 30 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2024 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
Expand Down Expand Up @@ -37,6 +37,6 @@ class DummyFramebuffer : Framebuffer {
override fun bindTexture() {
}

override fun resize(size: Vec2i) {
override fun resize(size: Vec2i, scale: Float) {
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
* Copyright (C) 2020-2024 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
Expand All @@ -26,6 +26,7 @@ import de.bixilon.minosoft.config.profile.profiles.rendering.light.LightC
import de.bixilon.minosoft.config.profile.profiles.rendering.movement.MovementC
import de.bixilon.minosoft.config.profile.profiles.rendering.overlay.OverlayC
import de.bixilon.minosoft.config.profile.profiles.rendering.performance.PerformanceC
import de.bixilon.minosoft.config.profile.profiles.rendering.quality.QualityC
import de.bixilon.minosoft.config.profile.profiles.rendering.sky.SkyC
import de.bixilon.minosoft.config.profile.profiles.rendering.textures.TexturesC
import de.bixilon.minosoft.config.profile.storage.ProfileStorage
Expand Down Expand Up @@ -53,6 +54,7 @@ class RenderingProfile(
val overlay = OverlayC(this)
val sky = SkyC(this)
val textures = TexturesC(this)
val quality = QualityC(this)


override fun toString(): String {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Minosoft
* Copyright (C) 2020-2024 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/

package de.bixilon.minosoft.config.profile.profiles.rendering.quality

import de.bixilon.minosoft.config.profile.profiles.rendering.RenderingProfile
import de.bixilon.minosoft.config.profile.profiles.rendering.quality.resolution.ResolutionC

class QualityC(profile: RenderingProfile) {
val resolution = ResolutionC(profile)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Minosoft
* Copyright (C) 2020-2024 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/

package de.bixilon.minosoft.config.profile.profiles.rendering.quality.resolution

import de.bixilon.minosoft.config.profile.delegate.primitive.FloatDelegate
import de.bixilon.minosoft.config.profile.profiles.rendering.RenderingProfile

class ResolutionC(profile: RenderingProfile) {

/**
* Scale of the gui (and hud) framebuffer. If you change this, the font will look weird and maybe blurry. Do not change this.
*/
var guiScale by FloatDelegate(profile, 1.0f, ranges = arrayOf(0.0001f..4.0f))

/**
* Scale of the world (blocks, entities, particles, ...) framebuffer.
* If you lower this, the framebuffer will be smaller and thus performance should go up.
* This is only useful when your gpu is bottlenecked by the number of pixels/texels
* (e.g. if you make the window smaller, your fps go up)
* Otherwise do not change this, this will not reduce cpu load or gpu load of other stages.
*/
var worldScale by FloatDelegate(profile, 1.0f, ranges = arrayOf(0.0001f..4.0f))
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
* Copyright (C) 2020-2024 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
Expand Down Expand Up @@ -33,8 +33,8 @@ class FramebufferManager(
gui.init()

context.connection.events.listen<ResizeWindowEvent> {
world.framebuffer.resize(it.size)
gui.framebuffer.resize(it.size)
world.resize(it.size)
gui.resize(it.size)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
* Copyright (C) 2020-2024 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
Expand All @@ -13,6 +13,7 @@

package de.bixilon.minosoft.gui.rendering.framebuffer

import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.renderer.drawable.Drawable
import de.bixilon.minosoft.gui.rendering.system.base.BlendingFunctions
Expand Down Expand Up @@ -54,4 +55,9 @@ interface IntegratedFramebuffer : Drawable {
shader.use()
mesh.draw()
}

fun resize(size: Vec2i) = resize(size, 1.0f)
fun resize(size: Vec2i, scale: Float) {
framebuffer.resize(size, scale)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
* Copyright (C) 2020-2024 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
Expand All @@ -13,6 +13,8 @@

package de.bixilon.minosoft.gui.rendering.framebuffer.gui

import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.kutil.observer.DataObserver.Companion.observe
import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.framebuffer.FramebufferMesh
import de.bixilon.minosoft.gui.rendering.framebuffer.FramebufferShader
Expand All @@ -28,4 +30,15 @@ class GUIFramebuffer(
override val framebuffer: Framebuffer = context.system.createFramebuffer(color = true, depth = false)
override val mesh = FramebufferMesh(context)
override var polygonMode: PolygonModes = PolygonModes.DEFAULT

private var scale = 1.0f

override fun init() {
super.init()
context.connection.profiles.rendering.quality.resolution::guiScale.observe(this, instant = true) { this.scale = it }
}

override fun resize(size: Vec2i) {
super.resize(size, this.scale)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
* Copyright (C) 2020-2024 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
Expand All @@ -13,6 +13,8 @@

package de.bixilon.minosoft.gui.rendering.framebuffer.world

import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.kutil.observer.DataObserver.Companion.observe
import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.framebuffer.FramebufferMesh
import de.bixilon.minosoft.gui.rendering.framebuffer.FramebufferShader
Expand All @@ -35,6 +37,8 @@ class WorldFramebuffer(
override val mesh = FramebufferMesh(context)
override var polygonMode: PolygonModes = PolygonModes.DEFAULT

private var scale = 1.0f

override fun init() {
framebuffer.init()
defaultShader.load()
Expand All @@ -43,6 +47,7 @@ class WorldFramebuffer(
mesh.load()

overlay.init()
context.connection.profiles.rendering.quality.resolution::worldScale.observe(this, instant = true) { this.scale = it }
}

override fun postInit() {
Expand All @@ -56,4 +61,8 @@ class WorldFramebuffer(
super.draw()
overlay.draw()
}

override fun resize(size: Vec2i) {
super.resize(size, this.scale)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
* Copyright (C) 2020-2024 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
Expand Down Expand Up @@ -142,7 +142,7 @@ interface RenderSystem {

fun createIntUniformBuffer(data: IntArray = IntArray(0)): IntUniformBuffer
fun createFloatUniformBuffer(data: FloatBuffer): FloatUniformBuffer
fun createFramebuffer(color: Boolean, depth: Boolean): Framebuffer
fun createFramebuffer(color: Boolean, depth: Boolean, scale: Float = 1.0f): Framebuffer

fun createTextureManager(): TextureManager

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2024 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
Expand Down Expand Up @@ -28,5 +28,5 @@ interface Framebuffer {

fun bindTexture()

fun resize(size: Vec2i)
fun resize(size: Vec2i, scale: Float = 1.0f)
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class OpenGLRenderSystem(
}
if (value == null) {
glBindFramebuffer(GL_FRAMEBUFFER, 0)
viewport = context.window.size
} else {
check(value is OpenGLFramebuffer) { "Can not use non OpenGL framebuffer!" }
value.bind()
Expand Down Expand Up @@ -238,7 +239,7 @@ class OpenGLRenderSystem(
override fun readPixels(start: Vec2i, end: Vec2i): TextureBuffer {
val size = Vec2i(end.x - start.x, end.y - start.y)
val buffer = RGB8Buffer(size)
glReadPixels(start.x, start.y, end.x, end.y, GL_RGB8, GL_UNSIGNED_BYTE, buffer.data)
glReadPixels(start.x, start.y, end.x, end.y, GL_RGB8, GL_UNSIGNED_BYTE, buffer.data) // TODO: This is somehow through a GL_INVALID_ENUM error
return buffer
}

Expand All @@ -258,8 +259,8 @@ class OpenGLRenderSystem(
return IntOpenGLUniformBuffer(this, uniformBufferBindingIndex++, data)
}

override fun createFramebuffer(color: Boolean, depth: Boolean): OpenGLFramebuffer {
return OpenGLFramebuffer(this, context.window.size, color, depth)
override fun createFramebuffer(color: Boolean, depth: Boolean, scale: Float): OpenGLFramebuffer {
return OpenGLFramebuffer(this, context.window.size, scale, color, depth)
}

override fun createTextureManager(): OpenGLTextureManager {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
* Copyright (C) 2020-2024 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
Expand Down Expand Up @@ -29,9 +29,11 @@ import org.lwjgl.opengl.GL30.*
class OpenGLFramebuffer(
val system: OpenGLRenderSystem,
var size: Vec2i,
var scale: Float,
val color: Boolean,
val depth: Boolean,
) : Framebuffer {
private var scaled = size
override var state: FramebufferState = FramebufferState.PREPARING
private set

Expand All @@ -43,21 +45,23 @@ class OpenGLFramebuffer(

override fun init() {
check(state != FramebufferState.COMPLETE) { "Framebuffer is complete!" }
if (scale <= 0.0f) throw IllegalArgumentException("Invalid scale: $scale")
if (size.x <= 0 || size.y <= 0) throw IllegalArgumentException("Invalid framebuffer size: $size")
system.log { "Generated framebuffer buffer $this" }
id = glGenFramebuffers()
unsafeBind()

glViewport(0, 0, size.x, size.y)
this.scaled = if (scale == 1.0f) size else Vec2i(size.x * scale, size.y * scale)

if (color) {
val colorTexture = OpenGLFramebufferColorTexture(size)
val colorTexture = OpenGLFramebufferColorTexture(scaled)
this.colorTexture = colorTexture
colorTexture.init()
attach(colorTexture)
}

if (depth) {
val depth = OpenGLRenderbuffer(system, RenderbufferModes.DEPTH_COMPONENT24, size)
val depth = OpenGLRenderbuffer(system, RenderbufferModes.DEPTH_COMPONENT24, scaled)
this.depthBuffer = depth
depth.init()
attach(depth)
Expand All @@ -75,6 +79,7 @@ class OpenGLFramebuffer(
fun bind() {
check(state == FramebufferState.COMPLETE) { "Framebuffer is incomplete: $state" }
unsafeBind()
system.viewport = scaled
}

private fun unsafeBind() {
Expand Down Expand Up @@ -108,12 +113,14 @@ class OpenGLFramebuffer(
depthTexture?.bind(1)
}

override fun resize(size: Vec2i) {
if (size == this.size) {
override fun resize(size: Vec2i, scale: Float) {
if (size.x <= 0 || size.y <= 0) throw IllegalArgumentException("Invalid framebuffer size: $size")
if (size == this.size && this.scale == scale) {
return
}
colorTexture?.unload()
depthBuffer?.unload()
this.scale = scale
this.size = size
delete()
init()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
* Copyright (C) 2020-2024 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
Expand Down Expand Up @@ -190,6 +190,7 @@ class GLFWWindow(
setOpenGLVersion(3, 3, true)
}
glfwWindowHint(GLFW_VISIBLE, false.glfw)
glfwWindowHint(GLFW_ALPHA_BITS, 0)
glfwWindowHint(GLFW_DEPTH_BITS, 0)
glfwWindowHint(GLFW_STENCIL_BITS, 0)

Expand Down
12 changes: 5 additions & 7 deletions src/main/java/de/bixilon/minosoft/protocol/PlayerPublicKey.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,11 @@ class PlayerPublicKey(

constructor(nbt: JsonObject) : this(Instant.ofEpochMilli(nbt["expires_at"].toLong()), CryptManager.getPlayerPublicKey(nbt["key"].toString()), nbt["signature"].toString().fromBase64())

fun toNbt(): JsonObject {
return mapOf(
"expires_at" to expiresAt.epochSecond,
"key" to publicKey.encoded.toBase64(),
"signature" to signature.toBase64(),
)
}
fun toNbt() = mapOf(
"expires_at" to expiresAt.epochSecond,
"key" to publicKey.encoded.toBase64(),
"signature" to signature.toBase64(),
)

fun isExpired(): Boolean {
return expiresAt.isAfter(Instant.now())
Expand Down

0 comments on commit 91c0e2b

Please sign in to comment.