Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 15 additions & 1 deletion src/main/scala/io/computenode/cyfra/ImageUtility.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ import java.awt.image.BufferedImage
import java.io.File
import java.nio.file.Path
import javax.imageio.ImageIO
import javax.swing.JFrame
import javax.swing.JLabel
import javax.swing.ImageIcon
import java.awt.Component

object ImageUtility {
def renderToImage(arr: Array[(Float, Float, Float, Float)], n: Int, location: Path): Unit = renderToImage(arr, n, n, location)
def renderToImage(arr: Array[(Float, Float, Float, Float)], w: Int, h: Int, location: Path): Unit = {
def renderBufferedImg(arr: Array[(Float, Float, Float, Float)], w: Int, h: Int): BufferedImage = {
val image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB)
for (y <- 0 until h) {
for (x <- 0 until w) {
Expand All @@ -17,9 +21,19 @@ object ImageUtility {
image.setRGB(x, y, (iR << 16) | (iG << 8) | iB)
}
}
image
}

def renderToImage(arr: Array[(Float, Float, Float, Float)], w: Int, h: Int, location: Path): Unit = {
val image = renderBufferedImg(arr, w, h)
val outputFile = location.toFile
ImageIO.write(image, "png", outputFile)
}

def displayImageToWindow(image: BufferedImage, frame: JFrame): Unit = {
frame.getContentPane.getComponents.collectFirst { case label: JLabel =>
label.setIcon(new ImageIcon(image))
}
frame.repaint()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package io.computenode.cyfra.samples.slides

import io.computenode.cyfra.dsl.Value.{Float32, Int32, Vec4}
import io.computenode.cyfra.dsl.Expression.*
import io.computenode.cyfra.dsl.Value.*
import io.computenode.cyfra.dsl.*

import java.awt.image.BufferedImage
import java.io.File
import javax.imageio.ImageIO
import scala.concurrent.ExecutionContext.Implicits
import scala.concurrent.{Await, ExecutionContext}
import io.computenode.cyfra.dsl.Algebra.*
import io.computenode.cyfra.dsl.Algebra.given
import io.computenode.cyfra.dsl.given

import scala.concurrent.duration.DurationInt
import io.computenode.cyfra.dsl.Functions.*
import io.computenode.cyfra.dsl.Control.*
import io.computenode.cyfra.dsl.{Empty, GArray2DFunction, GSeq, GStruct, Vec4FloatMem}
import io.computenode.cyfra.{ImageUtility}

import javax.swing.JFrame
import java.awt.event.KeyAdapter
import java.awt.event.KeyEvent
import javax.swing.JLabel
import java.awt.Color
import javax.swing.ImageIcon

@main
def realTimeRendering =

val dim = 1024
val emptyImage = new BufferedImage(dim, dim, BufferedImage.TYPE_INT_RGB)
val frame = new JFrame("Cyfra Live Raytracing")
frame.getContentPane.add(new JLabel(new ImageIcon(emptyImage)))
frame.pack()
frame.setVisible(true)




def computeImage(xLimit : Int): GArray2DFunction[Empty, Vec4[Float32], Vec4[Float32]] = GArray2DFunction(dim, dim, {
case (_, (x: Int32, _), _) =>
when ((x < xLimit)){
(1f, 1f, 1f, 1f)
} otherwise{
(0f, 0f, 0f, 1f)
}
})

var xLimit = 0
frame.addKeyListener(new KeyAdapter {
override def keyPressed(e: KeyEvent): Unit = {
e.getKeyCode match {
case KeyEvent.VK_LEFT => xLimit = math.max(0, xLimit - 1)
case KeyEvent.VK_RIGHT => xLimit = math.min(dim, xLimit + 1)
case _ => ()
}
}
})

while (true) {
val mem = Vec4FloatMem(Array.fill(dim * dim)((0f,0f,0f,0f)))
val result = Await.result(mem.map(computeImage(xLimit)), 1.second)
val image = ImageUtility.renderBufferedImg(result, dim, dim)
ImageUtility.displayImageToWindow(image, frame)
}