magnified screen will display everything correctly scaled (but some buttons wont work for some reason)

This commit is contained in:
minjaesong
2022-08-10 00:04:26 +09:00
parent 6e0f9a5924
commit f4d8d72715
8 changed files with 171 additions and 110 deletions

View File

@@ -11,10 +11,7 @@ import com.badlogic.gdx.controllers.Controllers;
import com.badlogic.gdx.graphics.*;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.glutils.FloatFrameBuffer;
import com.badlogic.gdx.graphics.glutils.GLFrameBuffer;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.*;
import com.badlogic.gdx.utils.Disposable;
import com.badlogic.gdx.utils.GdxRuntimeException;
import com.badlogic.gdx.utils.JsonValue;
@@ -545,6 +542,8 @@ public class App implements ApplicationListener {
CommonResourcePool.INSTANCE.loadAll();
}
private FrameBuffer postProcessorOutFBO;
@Override
public void render() {
Gdx.gl.glDisable(GL20.GL_DITHER);
@@ -561,6 +560,7 @@ public class App implements ApplicationListener {
gdxClearAndSetBlend(.094f, .094f, .094f, 0f);
setCameraPosition(0, 0);
// draw splash screen when predefined screen is null
// because in normal operation, the only time screen == null is when the app is cold-launched
// you can't have a text drawn here :v
@@ -584,10 +584,13 @@ public class App implements ApplicationListener {
setScreen(notitle);
}
}
postProcessorOutFBO = renderFBO;
}
// draw the screen
else {
currentScreen.render(UPDATE_RATE);
postProcessorOutFBO = TerrarumPostProcessor.INSTANCE.draw(camera.combined, renderFBO);
}
KeyToggler.INSTANCE.update(currentScreen instanceof TerrarumIngame);
@@ -597,9 +600,32 @@ public class App implements ApplicationListener {
// nested FBOs are just not a thing in GL!
FrameBufferManager.end();
PostProcessor.INSTANCE.draw(camera.combined, renderFBO);
// process screenshot request
if (screenshotRequested) {
FrameBufferManager.begin(postProcessorOutFBO);
screenshotRequested = false;
try {
Pixmap p = Pixmap.createFromFrameBuffer(0, 0, scr.getWidth(), scr.getHeight());
PixmapIO.writePNG(Gdx.files.absolute(defaultDir+"/Screenshot-"+String.valueOf(System.currentTimeMillis())+".png"), p, 9, true);
p.dispose();
Terrarum.INSTANCE.getIngame().sendNotification("Screenshot taken");
}
catch (Throwable e) {
e.printStackTrace();
Terrarum.INSTANCE.getIngame().sendNotification("Failed to take screenshot: "+e.getMessage());
}
FrameBufferManager.end();
}
shaderPassthruRGBA.bind();
shaderPassthruRGBA.setUniformMatrix("u_projTrans", camera.combined);
shaderPassthruRGBA.setUniformi("u_texture", 0);
postProcessorOutFBO.getColorBufferTexture().bind(0);
fullscreenQuad.render(shaderPassthruRGBA, GL20.GL_TRIANGLES);
// process resize request
if (resizeRequested) {
resizeRequested = false;
@@ -607,22 +633,6 @@ public class App implements ApplicationListener {
}
// process screenshot request
if (screenshotRequested) {
screenshotRequested = false;
try {
Pixmap p = Pixmap.createFromFrameBuffer(0, 0, scr.getWidth(), scr.getHeight());
PixmapIO.writePNG(Gdx.files.absolute(defaultDir+"/Screenshot-"+String.valueOf(System.currentTimeMillis())+".png"), p, 9, true);
p.dispose();
Terrarum.INSTANCE.getIngame().sendNotification("Screenshot taken");
}
catch (Throwable e) {
e.printStackTrace();
Terrarum.INSTANCE.getIngame().sendNotification("Failed to take screenshot: "+e.getMessage());
}
}
splashDisplayed = true;
GLOBAL_RENDER_TIMER += 1;
@@ -720,12 +730,23 @@ public class App implements ApplicationListener {
logoBatch.end();
}
/**
* This resize takes the apparent screen size (i.e. zoomed size) as parameters.
*
* All other Terrarum's resize() must take real screen size. (i.e not zoomed)
*
* @param w0 the new width in pixels
* @param h0 the new height in pixels
*/
@Override
public void resize(int w, int h) {
public void resize(int w0, int h0) {
double magn = getConfigDouble("screenmagnifying");
int width = (int) Math.round(w / magn);
int height = (int) Math.round(h / magn);
int w = (w0%2==0)?w0:w0+1;
int h = (h0%2==0)?h0:h0+1;
float magn = (float) getConfigDouble("screenmagnifying");
int width = Math.round(w / magn);
int height = Math.round(h / magn);
printdbg(this, "Resize called: "+width+","+height);
@@ -735,9 +756,10 @@ public class App implements ApplicationListener {
//initViewPort(width, height);
scr.setDimension(width, height);
scr.setDimension(width, height, magn, w, h);
if (currentScreen != null) currentScreen.resize(scr.getWidth(), scr.getHeight());
TerrarumPostProcessor.INSTANCE.resize(scr.getWidth(), scr.getHeight());
updateFullscreenQuad(scr.getWidth(), scr.getHeight());
@@ -1085,7 +1107,7 @@ public class App implements ApplicationListener {
operationSystem = "WINDOWS";
defaultDir = System.getenv("APPDATA") + "/Terrarum";
}
else if (OS.contains("OS X")) {
else if (OS.contains("OS X") || OS.contains("MACOS")) { // OpenJDK for mac will still report "Mac OS X" with version number "10.16", even on Big Sur and beyond
operationSystem = "OSX";
defaultDir = System.getProperty("user.home") + "/Library/Application Support/Terrarum";
}

View File

@@ -223,16 +223,16 @@ object Terrarum : Disposable {
/** Position of the cursor in the world, rounded */
val mouseX: Double
get() = (WorldCamera.zoomedX + Gdx.input.x / (ingame?.screenZoom ?: 1f).times(scr.magn)).fmod(WorldCamera.worldWidth.toDouble())
get() = (WorldCamera.zoomedX + Gdx.input.x / (ingame?.screenZoom ?: 1f).times(scr.magn.toDouble())).fmod(WorldCamera.worldWidth.toDouble())
/** Position of the cursor in the world */
val mouseY: Double
get() = (WorldCamera.zoomedY + Gdx.input.y / (ingame?.screenZoom ?: 1f).times(scr.magn))
get() = (WorldCamera.zoomedY + Gdx.input.y / (ingame?.screenZoom ?: 1f).times(scr.magn.toDouble()))
/** Position of the cursor in the world, rounded */
val oldMouseX: Double
get() = (WorldCamera.zoomedX + (Gdx.input.x - Gdx.input.deltaX) / (ingame?.screenZoom ?: 1f).times(scr.magn)).fmod(WorldCamera.worldWidth.toDouble())
get() = (WorldCamera.zoomedX + (Gdx.input.x - Gdx.input.deltaX) / (ingame?.screenZoom ?: 1f).times(scr.magn.toDouble())).fmod(WorldCamera.worldWidth.toDouble())
/** Position of the cursor in the world */
val oldMouseY: Double
get() = WorldCamera.zoomedY + (Gdx.input.y - Gdx.input.deltaY) / (ingame?.screenZoom ?: 1f).times(scr.magn)
get() = WorldCamera.zoomedY + (Gdx.input.y - Gdx.input.deltaY) / (ingame?.screenZoom ?: 1f).times(scr.magn.toDouble())
/** Position of the cursor in the world, rounded */
@JvmStatic val mouseTileX: Int
get() = (mouseX / TILE_SIZE).floorInt()

View File

@@ -2,10 +2,7 @@ package net.torvald.terrarum
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.Input
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.GL20
import com.badlogic.gdx.graphics.OrthographicCamera
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.*
import com.badlogic.gdx.graphics.glutils.FrameBuffer
import com.badlogic.gdx.graphics.glutils.ShapeRenderer
import com.badlogic.gdx.math.Matrix4
@@ -20,7 +17,7 @@ import net.torvald.terrarum.ui.Toolkit
*
* We recommened most of the user interfaces to be contained within the UI Area which has aspect ratio of 3:2.
*/
object PostProcessor : Disposable {
object TerrarumPostProcessor : Disposable {
private lateinit var batch: FlippingSpriteBatch // not nulling to save some lines of code
private lateinit var shapeRenderer: ShapeRenderer
@@ -30,6 +27,8 @@ object PostProcessor : Disposable {
private var init = false
private lateinit var outFBO: FrameBuffer
fun reloadLUT(filename: String) {
lutTex = Texture(Gdx.files.internal("assets/clut/$filename"))
}
@@ -62,19 +61,22 @@ object PostProcessor : Disposable {
App.disposables.add(this)
}
fun resize(w: Int, h: Int) {
try { outFBO.dispose() } catch (_: UninitializedPropertyAccessException) {}
outFBO = FrameBuffer(Pixmap.Format.RGBA8888, w, h, false)
}
override fun dispose() {
batch.dispose()
shapeRenderer.dispose()
functionRowHelper.dispose()
try {
lutTex.dispose()
}
catch (e: UninitializedPropertyAccessException) { }
try { lutTex.dispose() } catch (_: UninitializedPropertyAccessException) {}
shaderPostDither.dispose()
shaderPostNoDither.dispose()
outFBO.dispose()
}
fun draw(projMat: Matrix4, fbo: FrameBuffer) {
fun draw(projMat: Matrix4, fbo: FrameBuffer): FrameBuffer {
// init
if (!init) {
@@ -89,65 +91,72 @@ object PostProcessor : Disposable {
batch.projectionMatrix = camera.combined
shapeRenderer = ShapeRenderer()
shapeRenderer.projectionMatrix = camera.combined
Gdx.gl20.glViewport(0, 0, App.scr.width, App.scr.height)
resize(App.scr.width, App.scr.height)
}
debugUI.update(Gdx.graphics.deltaTime)
outFBO.inAction(camera, batch) {
App.measureDebugTime("Renderer.PostProcessor") {
App.measureDebugTime("Renderer.PostProcessor") {
gdxClearAndSetBlend(.094f, .094f, .094f, 0f)
gdxClearAndSetBlend(.094f, .094f, .094f, 0f)
fbo.colorBufferTexture.setFilter(
Texture.TextureFilter.Linear,
if (App.scr.magn % 1.0 < 0.0001) Texture.TextureFilter.Nearest else Texture.TextureFilter.Linear
)
fbo.colorBufferTexture.setFilter(
Texture.TextureFilter.Linear,
if (App.scr.magn % 1.0 < 0.0001) Texture.TextureFilter.Nearest else Texture.TextureFilter.Linear
)
postShader(projMat, fbo)
postShader(projMat, fbo)
// draw things when F keys are on
if (App.IS_DEVELOPMENT_BUILD && KeyToggler.isOn(Input.Keys.F11)) {
drawSafeArea()
}
if (KeyToggler.isOn(Input.Keys.F1)) {
batch.color = Color.WHITE
batch.inUse {
it.draw(functionRowHelper,
(App.scr.width - functionRowHelper.width) / 2f,
functionRowHelper.height.toFloat(),
functionRowHelper.width.toFloat(),
functionRowHelper.height * -1f
)
// draw things when F keys are on
if (App.IS_DEVELOPMENT_BUILD && KeyToggler.isOn(Input.Keys.F11)) {
drawSafeArea()
}
}
if (KeyToggler.isOn(Input.Keys.F10)) {
batch.color = Color.WHITE
batch.inUse {
App.fontSmallNumbers.draw(it, "Wire draw class: ${(Terrarum.ingame as? net.torvald.terrarum.modulebasegame.TerrarumIngame)?.selectedWireRenderClass}", 2f, 2f)
if (KeyToggler.isOn(Input.Keys.F1)) {
batch.color = Color.WHITE
batch.inUse {
it.draw(functionRowHelper,
(App.scr.width - functionRowHelper.width) / 2f,
0f,
functionRowHelper.width.toFloat(),
functionRowHelper.height.toFloat()
)
}
}
}
if (KeyToggler.isOn(Input.Keys.F3)) {
if (!debugUI.isOpened && !debugUI.isOpening) debugUI.setAsOpen()
batch.inUse { debugUI.renderUI(batch, camera) }
}
else {
if (!debugUI.isClosed && !debugUI.isClosing) debugUI.setAsClose()
}
if (KeyToggler.isOn(Input.Keys.F10)) {
batch.color = Color.WHITE
batch.inUse {
App.fontSmallNumbers.draw(it, "Wire draw class: ${(Terrarum.ingame as? net.torvald.terrarum.modulebasegame.TerrarumIngame)?.selectedWireRenderClass}", 2f, 2f)
}
}
// draw dev build notifiers
if (App.IS_DEVELOPMENT_BUILD && Terrarum.ingame != null) {
batch.inUse {
batch.color = safeAreaCol
App.fontGame.draw(it, thisIsDebugStr, 5f, App.scr.height - 24f)
if (KeyToggler.isOn(Input.Keys.F3)) {
if (!debugUI.isOpened && !debugUI.isOpening) debugUI.setAsOpen()
batch.inUse { debugUI.renderUI(batch, camera) }
}
else {
if (!debugUI.isClosed && !debugUI.isClosing) debugUI.setAsClose()
}
// draw dev build notifiers
if (App.IS_DEVELOPMENT_BUILD && Terrarum.ingame != null) {
batch.inUse {
batch.color = safeAreaCol
App.fontGame.draw(it, thisIsDebugStr, 5f, App.scr.height - 24f)
}
}
}
}
return outFBO
}
private val rng = HQRNG()
@@ -176,40 +185,49 @@ object PostProcessor : Disposable {
}
private fun drawSafeArea() {
val magn = App.scr.magn
val tvSafeAreaW = App.scr.tvSafeGraphicsWidth.toFloat()
val tvSafeAreaH = App.scr.tvSafeGraphicsHeight.toFloat()
val tvSafeArea2W = App.scr.tvSafeActionWidth.toFloat()
val tvSafeArea2H = App.scr.tvSafeActionHeight.toFloat()
val uiAreaHeight = App.scr.height - 2 * tvSafeAreaH
val uiAreaWidth = uiAreaHeight * recommendRatio
val scrw = Toolkit.drawWidthf
val scrw = Toolkit.drawWidthf * magn
val scrh = App.scr.hf * magn
val rect2W = tvSafeArea2W * magn
val rect2H = tvSafeArea2H * magn
val rectW = tvSafeAreaW * magn
val rectH = tvSafeAreaH * magn
shapeRenderer.inUse(ShapeRenderer.ShapeType.Line) {
// centre ind
shapeRenderer.color = safeAreaCol2
shapeRenderer.line(0f, 0f, scrw, App.scr.hf)
shapeRenderer.line(0f, App.scr.hf, scrw, 0f)
shapeRenderer.line(0f, 0f, scrw, scrh)
shapeRenderer.line(0f, scrh, scrw, 0f)
// safe action area
shapeRenderer.color = safeAreaCol2
shapeRenderer.rect(
tvSafeArea2W, tvSafeArea2H, scrw - 2 * tvSafeArea2W, App.scr.height - 2 * tvSafeArea2H
rect2W, rect2H, scrw - 2 * rect2W, App.scr.height * magn - 2 * rect2H
)
// safe graphics area
shapeRenderer.color = safeAreaCol
shapeRenderer.rect(
tvSafeAreaW, tvSafeAreaH, scrw - 2 * tvSafeAreaW, App.scr.height - 2 * tvSafeAreaH
rectW, rectH, scrw - 2 * rectW, App.scr.height * magn - 2 * rectH
)
// default res ind
shapeRenderer.color = defaultResCol
shapeRenderer.rect(
(scrw - uiAreaWidth).div(2f),
(App.scr.height - uiAreaHeight).div(2f),
uiAreaWidth,
uiAreaHeight
(scrw - uiAreaWidth * magn).div(2f),
(App.scr.height - uiAreaHeight).times(magn).div(2f),
uiAreaWidth * magn,
uiAreaHeight * magn
)
}
@@ -224,14 +242,14 @@ object PostProcessor : Disposable {
batch.color = defaultResCol
App.fontSmallNumbers.draw(
batch, defaultResStr,
(scrw - uiAreaWidth).div(2f),
(Toolkit.drawWidthf - uiAreaWidth).div(2f),
tvSafeAreaH
)
batch.color = currentResCol
App.fontSmallNumbers.draw(
batch, currentResStr,
scrw - 80f,
Toolkit.drawWidthf - 80f,
0f
)
}

View File

@@ -1,5 +1,6 @@
package net.torvald.terrarum
import net.torvald.terrarum.App.printdbg
import kotlin.math.roundToInt
class TerrarumScreenSize(scrw: Int = defaultW, scrh: Int = defaultH) {
@@ -25,18 +26,21 @@ class TerrarumScreenSize(scrw: Int = defaultW, scrh: Int = defaultH) {
var aspectRatio: Float = 0f; private set
var chatWidth: Int = 0; private set
var magn: Double = 0.0; private set // this value is stored here so that the initial instance would stay, forcing the players to require restart to apply the screen magnifying
var magn: Float = 0f; private set // this value is stored here so that the initial instance would stay, forcing the players to require restart to apply the screen magnifying
val tvSafeGraphicsWidth: Int; get() = Math.round(width * TV_SAFE_GRAPHICS)
val tvSafeGraphicsHeight: Int; get() = Math.round(height * TV_SAFE_GRAPHICS)
val tvSafeActionWidth: Int; get() = Math.round(width * TV_SAFE_ACTION)
val tvSafeActionHeight: Int; get() = Math.round(height * TV_SAFE_ACTION)
var windowW: Int = 0; private set
var windowH: Int = 0; private set
init {
setDimension(maxOf(minimumW, scrw), maxOf(minimumH, scrh))
setDimension(maxOf(minimumW, scrw), maxOf(minimumH, scrh), App.getConfigDouble("screenmagnifying").toFloat(), maxOf(minimumW, scrw), maxOf(minimumH, scrh))
}
fun setDimension(scrw: Int, scrh: Int) {
fun setDimension(scrw: Int, scrh: Int, magn: Float, ww: Int, wh: Int) {
width = scrw and 0x7FFFFFFE
height = scrh and 0x7FFFFFFE
wf = scrw.toFloat()
@@ -48,7 +52,14 @@ class TerrarumScreenSize(scrw: Int = defaultW, scrh: Int = defaultH) {
aspectRatio = wf / hf
chatWidth = (width - (width * 0.84375).roundToInt()) and 0x7FFFFFFE
magn = App.getConfigDouble("screenmagnifying")
this.magn = magn
windowW = ww
windowH = wh
printdbg(this, "Window dim: $ww x $wh, called by:")
printStackTrace(this)
}
}

View File

@@ -11,7 +11,8 @@ import com.badlogic.gdx.utils.Disposable
import com.badlogic.gdx.utils.GdxRuntimeException
import net.torvald.random.HQRNG
import net.torvald.terrarum.*
import net.torvald.terrarum.App.measureDebugTime
import net.torvald.terrarum.App.*
import net.torvald.terrarum.Terrarum.ingame
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF
import net.torvald.terrarum.gameactors.ActorWithBody
@@ -28,6 +29,9 @@ import net.torvald.terrarum.worlddrawer.WorldCamera
import net.torvald.util.CircularArray
import kotlin.system.exitProcess
/**
* This will be rendered to a postprocessor FBO.
*
@@ -409,6 +413,10 @@ object IngameRenderer : Disposable {
blendNormal(batch)
}
/**
* This "screencap" will capture the game WITHOUT gui and postprocessors!
* To capture the entire game, use [App.requestScreenshot]
*/
@Volatile internal var screencapRequested = false
@Volatile internal var fboRGBexportedLatch = false
@Volatile internal var screencapExportCallback: (FrameBuffer) -> Unit = {}

View File

@@ -347,7 +347,7 @@ class TitleScreen(batch: FlippingSpriteBatch) : IngameInstance(batch) {
)
}
App.fontGame.draw(batch, PostProcessor.thisIsDebugStr, 5f, App.scr.height - 24f)
App.fontGame.draw(batch, TerrarumPostProcessor.thisIsDebugStr, 5f, App.scr.height - 24f)

View File

@@ -72,19 +72,25 @@ class UIInventoryFull(
App.disposables.add(shapeRenderer)
}
val magn = App.scr.magn
val gradTopStart = -YPOS_CORRECTION + (App.scr.height - internalHeight).div(2).toFloat()
val gradBottomEnd = App.scr.height - gradTopStart
val gradTopStart0 = -YPOS_CORRECTION + (App.scr.height - internalHeight).div(2).toFloat()
val gradTopStart = gradTopStart0 * magn
val gradBottomEnd = (App.scr.height - gradTopStart0) * magn
val gradHeightFlat = (2*YPOS_CORRECTION + internalHeight - (2 * gradHeight)) * magn
val gradHeight = gradHeight * magn
val w = App.scr.wf * magn
val h = App.scr.hf * magn
shapeRenderer!!.inUse {
// shaperender starts at bottom-left!
it.rect(0f, gradTopStart, App.scr.wf, gradHeight, gradStartCol, gradStartCol, gradEndCol, gradEndCol)
it.rect(0f, gradBottomEnd, App.scr.wf, -gradHeight, gradStartCol, gradStartCol, gradEndCol, gradEndCol)
it.rect(0f, gradTopStart, w, gradHeight, gradStartCol, gradStartCol, gradEndCol, gradEndCol)
it.rect(0f, gradBottomEnd, w, -gradHeight, gradStartCol, gradStartCol, gradEndCol, gradEndCol)
it.rect(0f, gradTopStart + gradHeight, App.scr.wf, 2*YPOS_CORRECTION + internalHeight - (2 * gradHeight), gradEndCol, gradEndCol, gradEndCol, gradEndCol)
it.rect(0f, gradTopStart + gradHeight, w, gradHeightFlat, gradEndCol, gradEndCol, gradEndCol, gradEndCol)
it.rect(0f, 0f, App.scr.wf, gradTopStart, gradStartCol, gradStartCol, gradStartCol, gradStartCol)
it.rect(0f, App.scr.hf, App.scr.wf, -(App.scr.hf - gradBottomEnd), gradStartCol, gradStartCol, gradStartCol, gradStartCol)
it.rect(0f, 0f, w, gradTopStart, gradStartCol, gradStartCol, gradStartCol, gradStartCol)
it.rect(0f, h, w, -(h - gradBottomEnd), gradStartCol, gradStartCol, gradStartCol, gradStartCol)
}
batch.begin()

View File

@@ -5,7 +5,6 @@ import com.badlogic.gdx.graphics.*
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g2d.TextureRegion
import com.badlogic.gdx.graphics.glutils.FrameBuffer
import com.badlogic.gdx.graphics.glutils.ShapeRenderer
import net.torvald.unicode.getKeycapConsole
import net.torvald.unicode.getKeycapPC
import net.torvald.terrarum.*
@@ -33,8 +32,6 @@ class UITitleModules(val remoCon: UIRemoCon) : UICanvas() {
override var openCloseTime: Second = 0f
private val shapeRenderer = ShapeRenderer()
internal val uiWidth = MODULEINFO_CELL_WIDTH
internal val uiX: Int
@@ -255,7 +252,6 @@ class UITitleModules(val remoCon: UIRemoCon) : UICanvas() {
}
override fun dispose() {
try { shapeRenderer.dispose() } catch (e: IllegalArgumentException) {}
try { sliderFBO.dispose() } catch (e: IllegalArgumentException) {}
}