Skip to content

Commit

Permalink
Changes output of capture to an image type rather than a byte array
Browse files Browse the repository at this point in the history
  • Loading branch information
hobnob committed Oct 11, 2024
1 parent 64076f6 commit 0505d70
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import indigo.shared.datatypes.mutable.CheapMatrix4
import indigo.shared.platform.ProcessedSceneData
import indigo.shared.shader.RawShaderCode
import indigo.shared.time.Seconds
import indigo.shared.ImageData
import indigo.shared.ImageType

trait Renderer:
def renderingTechnology: RenderingTechnology
Expand All @@ -20,8 +22,9 @@ trait Renderer:
def drawScene(sceneData: ProcessedSceneData, runningTime: Seconds): Unit
def captureScreen(
clippingRect: Rectangle = Rectangle(Size(screenWidth, screenHeight)),
excludeLayers: Batch[BindingKey] = Batch.empty
): Batch[Byte]
excludeLayers: Batch[BindingKey] = Batch.empty,
imageType: ImageType = ImageType.PNG
): ImageData

object Renderer:
def blackHole = new Renderer {
Expand All @@ -30,7 +33,11 @@ object Renderer:
def screenHeight: Int = 0
def orthographicProjectionMatrix: CheapMatrix4 = CheapMatrix4.identity

def init(shaders: Set[RawShaderCode]): Unit = ()
def drawScene(sceneData: ProcessedSceneData, runningTime: Seconds): Unit = ()
def captureScreen(clippingRect: Rectangle, excludeLayers: Batch[BindingKey]): Batch[Byte] = Batch.empty
def init(shaders: Set[RawShaderCode]): Unit = ()
def drawScene(sceneData: ProcessedSceneData, runningTime: Seconds): Unit = ()
def captureScreen(
clippingRect: Rectangle,
excludeLayers: Batch[BindingKey],
imageType: ImageType = ImageType.PNG
): ImageData = ImageData(0, ImageType.PNG, Array.emptyByteArray)
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ import org.scalajs.dom.WebGLUniformLocation
import org.scalajs.dom.html

import scala.scalajs.js.typedarray.Float32Array
import indigo.shared.ImageData
import indigo.shared.ImageType

final class RendererWebGL1(
config: RendererConfig,
Expand Down Expand Up @@ -106,11 +108,13 @@ final class RendererWebGL1(
@SuppressWarnings(Array("scalafix:DisableSyntax.defaultArgs"))
clippingRect: Rectangle = Rectangle(Size(screenWidth, screenHeight)),
@SuppressWarnings(Array("scalafix:DisableSyntax.defaultArgs"))
excludeLayers: Batch[BindingKey] = Batch.empty
): Batch[Byte] = {
excludeLayers: Batch[BindingKey] = Batch.empty,
@SuppressWarnings(Array("scalafix:DisableSyntax.defaultArgs"))
imageType: ImageType = ImageType.PNG
): ImageData = {
val canvas = dom.document.createElement("canvas").asInstanceOf[html.Canvas]
val ctx = canvas.getContext("webgl1", cNc.context.getContextAttributes()).asInstanceOf[WebGLRenderingContext]

val ctx2d = canvas.getContext("2d").asInstanceOf[dom.CanvasRenderingContext2D]
val renderer = new RendererWebGL1(
config,
loadedTextureAssets,
Expand All @@ -120,24 +124,22 @@ final class RendererWebGL1(

renderer.drawScene(_prevSceneData, _prevGameRuntime)

val imageData = Batch.fromArray(
canvas
.getContext("2d")
.asInstanceOf[dom.CanvasRenderingContext2D]
val imageData =
ctx2d
.getImageData(
clippingRect.x,
clippingRect.y,
clippingRect.width,
clippingRect.height
)
.data
.map(_.toByte)
.toArray
)

ctx2d.clearRect(0, 0, canvas.width.toDouble, canvas.height.toDouble)
ctx2d.putImageData(imageData, 0, 0)

val data = canvas.toDataURL(imageType.toString()).split(",")(1).grouped(4).map(_.toInt.toByte).toArray
canvas.remove()

imageData
ImageData(data.length, imageType, data)
}

def drawScene(sceneData: ProcessedSceneData, runningTime: Seconds): Unit = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ import org.scalajs.dom.html

import scala.scalajs.js.Dynamic
import scala.scalajs.js.typedarray.Float32Array
import indigo.shared.ImageType
import indigo.shared.ImageData

@SuppressWarnings(Array("scalafix:DisableSyntax.null"))
final class RendererWebGL2(
Expand Down Expand Up @@ -236,11 +238,13 @@ final class RendererWebGL2(
@SuppressWarnings(Array("scalafix:DisableSyntax.defaultArgs"))
clippingRect: Rectangle = Rectangle(Size(screenWidth, screenHeight)),
@SuppressWarnings(Array("scalafix:DisableSyntax.defaultArgs"))
excludeLayers: Batch[BindingKey] = Batch.empty
): Batch[Byte] = {
excludeLayers: Batch[BindingKey] = Batch.empty,
@SuppressWarnings(Array("scalafix:DisableSyntax.defaultArgs"))
imageType: ImageType = ImageType.PNG
): ImageData = {
val canvas = dom.document.createElement("canvas").asInstanceOf[html.Canvas]
val ctx = canvas.getContext("webgl2", cNc.context.getContextAttributes()).asInstanceOf[WebGLRenderingContext]

val ctx2d = canvas.getContext("2d").asInstanceOf[dom.CanvasRenderingContext2D]
val renderer = new RendererWebGL2(
config,
loadedTextureAssets,
Expand All @@ -252,24 +256,22 @@ final class RendererWebGL2(
renderer.customShaders ++= customShaders
renderer.drawScene(_prevSceneData, _prevGameRuntime)

val imageData = Batch.fromArray(
canvas
.getContext("2d")
.asInstanceOf[dom.CanvasRenderingContext2D]
val imageData =
ctx2d
.getImageData(
clippingRect.x,
clippingRect.y,
clippingRect.width,
clippingRect.height
)
.data
.map(_.toByte)
.toArray
)

ctx2d.clearRect(0, 0, canvas.width.toDouble, canvas.height.toDouble)
ctx2d.putImageData(imageData, 0, 0)

val data = canvas.toDataURL(imageType.toString()).split(",")(1).grouped(4).map(_.toInt.toByte).toArray
canvas.remove()

imageData
ImageData(data.length, imageType, data)
}

def drawScene(sceneData: ProcessedSceneData, runningTime: Seconds): Unit = {
Expand Down
12 changes: 12 additions & 0 deletions indigo/indigo/src/main/scala/indigo/shared/ImageData.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package indigo.shared

enum ImageType derives CanEqual:
case JPEG, PNG, WEBP

override def toString(): String = this match {
case ImageType.JPEG => "image/jpeg"
case ImageType.PNG => "image/png"
case ImageType.WEBP => "image/webp"
}

final case class ImageData(size: Int, `type`: ImageType, data: Array[Byte])

0 comments on commit 0505d70

Please sign in to comment.