Add nice frame to the screen

This commit is contained in:
LeshaInc 2019-01-10 17:13:13 +02:00
parent 96e29edbf6
commit d7c084c0dd
No known key found for this signature in database
GPG Key ID: B4855290FC36DE72
8 changed files with 142 additions and 15 deletions

View File

@ -8,5 +8,5 @@ out vec4 outColor;
uniform sampler2D uTexture;
void main() {
outColor = fColor;
outColor = texture(uTexture, fUV) * fColor;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@ -0,0 +1,27 @@
APU0 0 0 16 16
APU1 16 0 16 16
APU2 32 0 16 16
BorderH 96 32 2 8
BorderV 98 32 8 2
CPU0 48 0 16 16
CPU1 64 0 16 16
CPU2 80 0 16 16
CornerBL 64 32 8 8
CornerBR 72 32 8 8
CornerTL 80 32 8 8
CornerTR 88 32 8 8
EEPROM 96 0 16 16
Empty 106 32 1 1
GraphicsCard0 112 0 16 16
GraphicsCard1 0 16 16 16
GraphicsCard2 16 16 16 16
HardDiskDrive0 32 16 16 16
HardDiskDrive1 48 16 16 16
HardDiskDrive2 64 16 16 16
InternetCard 80 16 16 16
Memory0 96 16 16 16
Memory1 112 16 16 16
Memory2 0 32 16 16
Memory3 16 32 16 16
Memory4 32 32 16 16
Memory5 48 32 16 16

View File

@ -1,10 +1,10 @@
package ocelot.desktop.graphics
import ocelot.desktop.color.{Color, RGBAColorNorm}
import ocelot.desktop.color.{Color, IntColor, RGBAColorNorm}
import ocelot.desktop.geometry.Transform2D
import ocelot.desktop.graphics.mesh.{Mesh, MeshInstance}
import ocelot.desktop.graphics.render.InstanceRenderer
import ocelot.desktop.util.FontLoader
import ocelot.desktop.util.{FontLoader, Spritesheet}
import org.apache.logging.log4j.scala.Logging
import org.lwjgl.opengl.GL11
@ -24,6 +24,10 @@ class Graphics extends Logging {
private var _background = RGBAColorNorm(0f, 0f, 0f, 1f)
private var _fontSize: Float = 16f
private var _sprite: String = "Empty"
private var spriteRect = Spritesheet.sprites(_sprite)
private val emptySpriteTrans = Transform2D.translate(spriteRect.x, spriteRect.y) >> Transform2D.scale(spriteRect.w, spriteRect.h)
GL11.glEnable(GL11.GL_DEPTH_TEST)
GL11.glDepthFunc(GL11.GL_LEQUAL)
GL11.glEnable(GL11.GL_BLEND)
@ -74,6 +78,13 @@ class Graphics extends Logging {
_fontSize = value
}
def sprite: String = _sprite
def sprite_=(value: String): Unit = {
_sprite = value
spriteRect = Spritesheet.sprites(_sprite)
}
def text(x: Float, y: Float, text: String): Unit = {
var ox = x
@ -105,24 +116,34 @@ class Graphics extends Logging {
// ^ dirty hack to avoid edge bleeding, somehow works
)
rectRenderer.schedule(MeshInstance(_background, z, Transform2D.translate(x, y) >> Transform2D.scale(width, height)))
rectRenderer.schedule(MeshInstance(_background, z, Transform2D.translate(x, y) >> Transform2D.scale(width, height), emptySpriteTrans))
textRenderer.schedule(MeshInstance(_foreground, z + 1, Transform2D.translate(x, y) >> Transform2D.scale(width, height), uvTransform))
z += 2
}
def sprite(name: String, x: Float, y: Float, width: Float, height: Float): Unit = {
flush()
sprite = name
background = RGBAColorNorm(1f, 1f, 1f, 1f)
rect(x, y, width, height)
}
def rect(x: Float, y: Float, width: Float, height: Float): Unit = {
rectRenderer.schedule(MeshInstance(_background, z, Transform2D.translate(x, y) >> Transform2D.scale(width, height)))
val uvTransform = Transform2D.translate(spriteRect.x, spriteRect.y) >> Transform2D.scale(spriteRect.w, spriteRect.h)
rectRenderer.schedule(MeshInstance(_background, z, Transform2D.translate(x, y) >> Transform2D.scale(width, height), uvTransform))
z += 1
}
def flush(): Unit = {
Spritesheet.texture.bind()
rectRenderer.flush()
fontAtlas.bind()
textRenderer.flush()
}
def commit(): Unit = {
Spritesheet.texture.bind()
rectRenderer.commit()
fontAtlas.bind()
textRenderer.commit()

View File

@ -1,9 +1,11 @@
package ocelot.desktop.graphics
import java.awt.image.BufferedImage
import java.nio.ByteBuffer
import ocelot.desktop.util.{Resource, ResourceManager}
import org.apache.logging.log4j.scala.Logging
import org.lwjgl.BufferUtils
import org.lwjgl.opengl._
import org.lwjgl.system.MemoryUtil.NULL
@ -21,6 +23,31 @@ class Texture extends Logging with Resource {
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST)
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST)
def this(image: BufferedImage) {
this()
val pixels = new Array[Int](image.getWidth * image.getHeight)
image.getRGB(0, 0, image.getWidth, image.getHeight, pixels, 0, image.getWidth)
val buf = BufferUtils.createByteBuffer(image.getWidth * image.getHeight * 4)
for (y <- 0 until image.getHeight) {
for (x <- 0 until image.getWidth) {
val pixel = pixels(y * image.getWidth + x)
buf.put(((pixel >> 16) & 0xFF).toByte)
buf.put(((pixel >> 8) & 0xFF).toByte)
buf.put((pixel & 0xFF).toByte)
buf.put(((pixel >> 24) & 0xFF).toByte)
}
}
buf.flip()
bind()
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, image.getWidth, image.getHeight, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buf)
GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D)
}
def this(width: Int, height: Int, format: Int, dataType: Int) = {
this()
bind()

View File

@ -5,7 +5,7 @@ import java.nio.{ByteBuffer, IntBuffer}
import ocelot.desktop.geometry.{Size2D, Vector2D}
import ocelot.desktop.graphics.Graphics
import ocelot.desktop.ui.widget.RootWidget
import ocelot.desktop.util.{Audio, FPSCalculator, FontLoader}
import ocelot.desktop.util.{Audio, FPSCalculator, FontLoader, Spritesheet}
import org.apache.logging.log4j.scala.Logging
import org.lwjgl.glfw.{GLFW, GLFWErrorCallback}
import org.lwjgl.openal._
@ -75,6 +75,7 @@ class UiHandler(val root: RootWidget) extends Logging {
logger.info(s"OpenGL renderer: ${GL11.glGetString(GL11.GL_RENDERER)}")
FontLoader.init()
Spritesheet.load()
graphics = new Graphics
soundDevice = ALC10.alcOpenDevice(null.asInstanceOf[ByteBuffer])

View File

@ -14,17 +14,17 @@ import scala.collection.mutable
class ScreenWidget(screen: Screen) extends RootWidget with Logging {
private val fontSize = 16f
var width = 80
var height = 25
var width = screen.getWidth
var height = screen.getHeight
var background: Int = 0x000000
var foreground: Int = 0xFFFFFF
private var data: Array[Cell] = Array.fill(width * height)(Cell(' ', background, foreground))
override def minimumSize: Option[Size2D] = Some(Size2D(width * fontSize / 2f, height * fontSize))
override def minimumSize: Option[Size2D] = Some(Size2D(width * fontSize / 2f + 32, height * fontSize + 32))
override def maximumSize: Option[Size2D] = Some(Size2D(width * fontSize, height * fontSize * 2f))
override def maximumSize: Option[Size2D] = minimumSize
private var lastMousePos = Vector2D(0, 0)
private var pressedMouseButtons = new mutable.HashSet[MouseEvent.Button.Value]()
@ -63,7 +63,7 @@ class ScreenWidget(screen: Screen) extends RootWidget with Logging {
screen.mouseScroll(lastMousePos.x, lastMousePos.y, event.offset, User("myself"))
}
def convertMousePos(p: Vector2D): Vector2D = Vector2D(p.x / fontSize * 2f, p.y / fontSize)
def convertMousePos(p: Vector2D): Vector2D = Vector2D((p.x - 16) / fontSize * 2f, (p.y - 16) / fontSize)
override def update(): Unit = {
val currentMousePos = convertMousePos(uiHandler.mousePosition)
@ -79,10 +79,14 @@ class ScreenWidget(screen: Screen) extends RootWidget with Logging {
override def windowTitle: String = f"Ocelot Desktop [FPS: ${uiHandler.fps}%2.3f]"
override def draw(g: Graphics): Unit = {
val tx = size.width / 2 - fontSize * width / 4
val ty = size.height / 2 - fontSize * height / 2
val w = math.round(fontSize * width / 2f) + 32
val h = math.round(fontSize * height) + 32
g.clear(0, 0, w, h)
g.background = IntColor(0x333333)
g.sprite = "Empty"
g.rect(0, 0, w, h)
g.clear(0, 0, math.round(fontSize * width / 2f), math.round(fontSize * height))
g.fontSize = fontSize
for (y <- 0 until height) {
@ -91,10 +95,19 @@ class ScreenWidget(screen: Screen) extends RootWidget with Logging {
val Cell(char, bg, fg) = data(y * width + x)
g.background = IntColor(bg)
g.foreground = IntColor(fg)
g.char(tx + x * fontSize / 2f, ty + y * fontSize, char)
g.char(x * fontSize / 2f + 16, y * fontSize + 16, char)
}
}
}
g.sprite("CornerTL", 0, 0, 16,16)
g.sprite("CornerTR", w - 16, 0, 16,16)
g.sprite("CornerBL", 0, h - 16, 16,16)
g.sprite("CornerBR", w - 16, h - 16, 16,16)
g.sprite("BorderH", 16, 0, w - 32, 16)
g.sprite("BorderH", 16, h - 16, w - 32, 16)
g.sprite("BorderV", 0, 16, 16, h - 32)
g.sprite("BorderV", w - 16, 16, 16, h - 32)
}
def set(x: Int, y: Int, text: String, vertical: Boolean): Unit = {

View File

@ -0,0 +1,38 @@
package ocelot.desktop.util
import javax.imageio.ImageIO
import ocelot.desktop.graphics.Texture
import org.apache.logging.log4j.scala.Logging
import scala.collection.mutable
import scala.io.Source
object Spritesheet extends Logging {
val sprites = new mutable.HashMap[String, Rect]()
var texture: Texture = _
def load(): Unit = {
logger.info("Loading sprites")
val imageURL = getClass.getResource("/ocelot/desktop/spritesheet.png")
val image = ImageIO.read(imageURL)
texture = new Texture(image)
val txt = Source.fromURL(getClass.getResource("/ocelot/desktop/spritesheet.txt"))
for (line <- txt.getLines) {
val split = line.split("\\s+")
sprites += (split.head -> Rect(
split(1).toFloat / image.getWidth.toFloat,
split(2).toFloat / image.getHeight.toFloat,
split(3).toFloat / image.getWidth.toFloat,
split(4).toFloat / image.getHeight.toFloat
))
logger.info(s"${split.head} -> ${sprites(split.head)}")
}
txt.close()
logger.info(s"Loaded ${sprites.size} sprites")
}
}