mirror of
https://gitlab.com/cc-ru/ocelot/ocelot-desktop.git
synced 2025-12-20 02:59:19 +01:00
Generate and use mipmaps for screen textures
This commit is contained in:
parent
acb1374140
commit
5e7777bd4c
@ -53,4 +53,9 @@ ocelot {
|
||||
# Otherwise, content will be shown only in windows
|
||||
renderScreenDataOnNodes: true
|
||||
}
|
||||
|
||||
render {
|
||||
# Whether mipmap scaling is enabled for screen windows (when shrinking).
|
||||
screenWindowMipmap: true
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,6 +50,8 @@ class Settings(val config: Config) extends SettingsData {
|
||||
saveOnExit = config.getBooleanOrElse("ocelot.workspace.saveOnExit", default = true)
|
||||
openLastWorkspace = config.getBooleanOrElse("ocelot.workspace.openLastWorkspace", default = true)
|
||||
renderScreenDataOnNodes = config.getBooleanOrElse("ocelot.workspace.renderScreenDataOnNodes", default = true)
|
||||
|
||||
screenWindowMipmap = config.getBooleanOrElse("ocelot.render.screenWindowMipmap", default = true)
|
||||
}
|
||||
|
||||
object Settings extends Logging {
|
||||
|
||||
@ -3,6 +3,7 @@ package ocelot.desktop.graphics
|
||||
import ocelot.desktop.color.{Color, RGBAColorNorm}
|
||||
import ocelot.desktop.geometry.{Rect2D, Size2D, Transform2D, Vector2D}
|
||||
import ocelot.desktop.graphics.IconSource.Animation
|
||||
import ocelot.desktop.graphics.Texture.MinFilteringMode
|
||||
import ocelot.desktop.graphics.mesh.{Mesh2D, MeshInstance2D, MeshVertex2D}
|
||||
import ocelot.desktop.graphics.render.InstanceRenderer
|
||||
import ocelot.desktop.ui.UiHandler
|
||||
@ -145,11 +146,19 @@ class Graphics(private var width: Int, private var height: Int, private var scal
|
||||
flush(mainTexture = viewport.textureColor)
|
||||
}
|
||||
|
||||
def blitScreenViewport(viewport: ScreenViewport, bounds: Rect2D, alpha: Float = 1.0f): Unit = {
|
||||
def blitScreenViewport(
|
||||
viewport: ScreenViewport,
|
||||
bounds: Rect2D,
|
||||
filteringMode: MinFilteringMode = MinFilteringMode.Nearest,
|
||||
alpha: Float = 1.0f
|
||||
): Unit = {
|
||||
flush()
|
||||
foreground = RGBAColorNorm(1, 1, 1, alpha)
|
||||
spriteRect = Rect2D(0, 1f, 1f, -1f)
|
||||
_rect(bounds.x, bounds.y, bounds.w, bounds.h, fixUV = false)
|
||||
|
||||
viewport.texture.setMinFilter(filteringMode)
|
||||
|
||||
flush(mainTexture = viewport.texture)
|
||||
}
|
||||
|
||||
|
||||
@ -27,6 +27,8 @@ class ScreenViewport(graphics: Graphics, private var _width: Int, private var _h
|
||||
private var _foreground: RGBAColorNorm = RGBAColorNorm(0f, 0f, 0f)
|
||||
private var _background: RGBAColorNorm = RGBAColorNorm(1f, 1f, 1f)
|
||||
|
||||
private var mipmapDirty = false
|
||||
|
||||
override def freeResource(): Unit = {
|
||||
super.freeResource()
|
||||
|
||||
@ -110,6 +112,8 @@ class ScreenViewport(graphics: Graphics, private var _width: Int, private var _h
|
||||
Spritesheet.texture.bind()
|
||||
_font.texture.bind(1)
|
||||
renderer.flush()
|
||||
|
||||
mipmapDirty = true
|
||||
}
|
||||
|
||||
def renderWith(f: => Unit): Unit = {
|
||||
@ -121,4 +125,11 @@ class ScreenViewport(graphics: Graphics, private var _width: Int, private var _h
|
||||
flush()
|
||||
}
|
||||
}
|
||||
|
||||
def generateMipmap(): Unit = {
|
||||
if (mipmapDirty) {
|
||||
texture.generateMipmap()
|
||||
mipmapDirty = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package ocelot.desktop.graphics
|
||||
|
||||
import ocelot.desktop.graphics.Texture.MinFilteringMode
|
||||
import ocelot.desktop.util.{Logging, Resource}
|
||||
import org.lwjgl.BufferUtils
|
||||
import org.lwjgl.opengl._
|
||||
@ -7,7 +8,7 @@ import org.lwjgl.opengl._
|
||||
import java.awt.image.BufferedImage
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
class Texture extends Logging with Resource {
|
||||
class Texture() extends Logging with Resource {
|
||||
val texture: Int = GL11.glGenTextures()
|
||||
|
||||
bind()
|
||||
@ -70,8 +71,30 @@ class Texture extends Logging with Resource {
|
||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture)
|
||||
}
|
||||
|
||||
def setMinFilter(filter: MinFilteringMode): Unit = {
|
||||
bind()
|
||||
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, filter.glValue)
|
||||
}
|
||||
|
||||
def generateMipmap(): Unit = {
|
||||
bind()
|
||||
GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D)
|
||||
}
|
||||
|
||||
override def freeResource(): Unit = {
|
||||
super.freeResource()
|
||||
GL11.glDeleteTextures(texture)
|
||||
}
|
||||
}
|
||||
|
||||
object Texture {
|
||||
class MinFilteringMode private(private[Texture] val glValue: Int, val needsMipmap: Boolean)
|
||||
|
||||
object MinFilteringMode {
|
||||
val Nearest = new MinFilteringMode(GL11.GL_NEAREST, false)
|
||||
val NearestMipmapNearest = new MinFilteringMode(GL11.GL_NEAREST_MIPMAP_NEAREST, true)
|
||||
val NearestMipmapLinear = new MinFilteringMode(GL11.GL_NEAREST_MIPMAP_LINEAR, true)
|
||||
val LinearMipmapNearest = new MinFilteringMode(GL11.GL_LINEAR_MIPMAP_NEAREST, true)
|
||||
val LinearMipmapLinear = new MinFilteringMode(GL11.GL_LINEAR_MIPMAP_LINEAR, true)
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package ocelot.desktop.node.nodes
|
||||
|
||||
import ocelot.desktop.color.{Color, IntColor}
|
||||
import ocelot.desktop.geometry.{Rect2D, Size2D}
|
||||
import ocelot.desktop.graphics.Texture.MinFilteringMode
|
||||
import ocelot.desktop.graphics.{Graphics, IconSource, ScreenViewport}
|
||||
import ocelot.desktop.node.Node.{HighlightThickness, NoHighlightSize, Size}
|
||||
import ocelot.desktop.node.nodes.ScreenNode.{FontHeight, FontWidth, Margin}
|
||||
@ -116,9 +117,8 @@ class ScreenNode(val screen: Screen)
|
||||
super.setupContextMenu(menu, event)
|
||||
}
|
||||
|
||||
private def drawScreenTexture(): Unit = {
|
||||
if (bufferRendered) return
|
||||
|
||||
private def drawScreenTexture(needsMipmap: Boolean): Unit = {
|
||||
if (!bufferRendered) {
|
||||
viewport.renderWith {
|
||||
val width = (screen.getWidth * FontWidth).toInt
|
||||
val height = (screen.getHeight * FontHeight).toInt
|
||||
@ -139,21 +139,33 @@ class ScreenNode(val screen: Screen)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bufferRendered = true
|
||||
}
|
||||
|
||||
if (needsMipmap) {
|
||||
viewport.generateMipmap()
|
||||
}
|
||||
}
|
||||
|
||||
def drawScreenData(g: Graphics, startX: Float, startY: Float, scaleX: Float, scaleY: Float): Unit = {
|
||||
def drawScreenData(
|
||||
g: Graphics,
|
||||
startX: Float,
|
||||
startY: Float,
|
||||
scaleX: Float,
|
||||
scaleY: Float,
|
||||
filteringMode: MinFilteringMode
|
||||
): Unit = {
|
||||
g.save()
|
||||
g.scale(scaleX, scaleY)
|
||||
|
||||
val startXScaled = startX / scaleX
|
||||
val startYScaled = startY / scaleY
|
||||
|
||||
drawScreenTexture()
|
||||
drawScreenTexture(filteringMode.needsMipmap)
|
||||
val bounds = Rect2D(startXScaled, startYScaled, viewport.width, viewport.height)
|
||||
g.blitScreenViewport(viewport, bounds)
|
||||
g.blitScreenViewport(viewport, bounds, filteringMode = filteringMode)
|
||||
|
||||
g.restore()
|
||||
}
|
||||
@ -351,7 +363,8 @@ class ScreenNode(val screen: Screen)
|
||||
virtualScreenBounds.x + virtualScreenBounds.w / 2 - (pixelDataSize.width * scale) / 2,
|
||||
virtualScreenBounds.y + virtualScreenBounds.h / 2 - (pixelDataSize.height * scale) / 2,
|
||||
scale,
|
||||
scale
|
||||
scale,
|
||||
MinFilteringMode.NearestMipmapNearest
|
||||
)
|
||||
}
|
||||
// Drawing simple overlay otherwise
|
||||
|
||||
@ -68,6 +68,15 @@ class UISettingsTab extends SettingsTab {
|
||||
}
|
||||
}, Padding2D(bottom = 8))
|
||||
|
||||
children :+= new PaddingBox(new Checkbox("Enable mipmaps for screen windows",
|
||||
initialValue = Settings.get.screenWindowMipmap) {
|
||||
override def minimumSize: Size2D = Size2D(512, 24)
|
||||
|
||||
override def onValueChanged(value: Boolean): Unit = {
|
||||
Settings.get.screenWindowMipmap = value
|
||||
}
|
||||
}, Padding2D(bottom = 8))
|
||||
|
||||
children :+= new PaddingBox(new Slider((Settings.get.scaleFactor - 1) / 2, "Interface scale", 5) {
|
||||
override def minimumSize: Size2D = Size2D(512, 24)
|
||||
|
||||
|
||||
@ -42,6 +42,8 @@ class SettingsData {
|
||||
var openLastWorkspace: Boolean = true
|
||||
var renderScreenDataOnNodes: Boolean = true
|
||||
|
||||
var screenWindowMipmap: Boolean = true
|
||||
|
||||
private val mirror = universe.runtimeMirror(getClass.getClassLoader).reflect(this)
|
||||
|
||||
def updateWith(data: SettingsData): Unit = {
|
||||
|
||||
@ -4,6 +4,7 @@ import ocelot.desktop.audio.SoundSource
|
||||
import ocelot.desktop.color.RGBAColor
|
||||
import ocelot.desktop.geometry.{Rect2D, Size2D, Vector2D}
|
||||
import ocelot.desktop.graphics.Graphics
|
||||
import ocelot.desktop.graphics.Texture.MinFilteringMode
|
||||
import ocelot.desktop.node.nodes.ScreenNode
|
||||
import ocelot.desktop.node.nodes.ScreenNode.{FontHeight, FontWidth}
|
||||
import ocelot.desktop.ui.UiHandler
|
||||
@ -12,7 +13,7 @@ import ocelot.desktop.ui.event.{DragEvent, KeyEvent, MouseEvent, ScrollEvent}
|
||||
import ocelot.desktop.ui.widget.window.BasicWindow
|
||||
import ocelot.desktop.util.{DrawUtils, Logging}
|
||||
import ocelot.desktop.windows.ScreenWindow._
|
||||
import ocelot.desktop.{ColorScheme, OcelotDesktop}
|
||||
import ocelot.desktop.{ColorScheme, OcelotDesktop, Settings}
|
||||
import org.apache.commons.lang3.StringUtils
|
||||
import org.lwjgl.input.Keyboard
|
||||
import totoro.ocelot.brain.entity.Screen
|
||||
@ -254,7 +255,12 @@ class ScreenWindow(screenNode: ScreenNode) extends BasicWindow with Logging {
|
||||
startX,
|
||||
startY,
|
||||
scaleX,
|
||||
scaleY
|
||||
scaleY,
|
||||
if (Settings.get.screenWindowMipmap) {
|
||||
MinFilteringMode.LinearMipmapLinear
|
||||
} else {
|
||||
MinFilteringMode.Nearest
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user