Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added FastEllipse and FastRoundRect versions using SDF #1382

Merged
merged 1 commit into from Mar 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -97,7 +97,7 @@ fun RenderContext2D.materialRoundRect(
//colorMul: RGBA = Colors.WHITE,
) {
_tempProgramUniforms.clear()
_tempProgramUniforms.set(MaterialRender.u_Radius, radius.bottomRight, radius.topRight, radius.bottomLeft, radius.topLeft,)
_tempProgramUniforms.set(MaterialRender.u_Radius, radius.bottomRight, radius.topRight, radius.bottomLeft, radius.topLeft)
_tempProgramUniforms.set(MaterialRender.u_Size, width, height)

_tempProgramUniforms[MaterialRender.u_BackgroundColor] = color.premultipliedFast
Expand Down
14 changes: 7 additions & 7 deletions korge/src/commonMain/kotlin/com/soywiz/korge/view/Ellipse.kt
Expand Up @@ -13,13 +13,13 @@ import com.soywiz.korma.geom.vector.*
* The [callback] allows to configure the [Circle] instance.
*/
inline fun Container.ellipse(
radiusX: Double = 16.0,
radiusY: Double = 16.0,
fill: Paint = Colors.WHITE,
stroke: Paint = Colors.WHITE,
strokeThickness: Double = 0.0,
autoScaling: Boolean = true,
callback: @ViewDslMarker Ellipse.() -> Unit = {}
radiusX: Double = 16.0,
radiusY: Double = 16.0,
fill: Paint = Colors.WHITE,
stroke: Paint = Colors.WHITE,
strokeThickness: Double = 0.0,
autoScaling: Boolean = true,
callback: @ViewDslMarker Ellipse.() -> Unit = {}
): Ellipse = Ellipse(radiusX, radiusY, fill, stroke, strokeThickness, autoScaling).addTo(this, callback)

/**
Expand Down
18 changes: 18 additions & 0 deletions korge/src/commonMain/kotlin/com/soywiz/korge/view/FastEllipse.kt
@@ -0,0 +1,18 @@
package com.soywiz.korge.view

import com.soywiz.korim.color.*
import com.soywiz.korma.geom.*

inline fun Container.fastEllipse(
size: Size,
color: RGBA = Colors.WHITE,
callback: @ViewDslMarker FastEllipse.() -> Unit = {}
) = FastEllipse(size.widthD, size.heightD).colorMul(color).addTo(this, callback)

open class FastEllipse(width: Double = 100.0, height: Double = 100.0) : FastRoundRectBase(
width, height, RectCorners(1f, 1f, 1f, 1f), doScale = false
) {
var radius: Size
get() = Size(width, height) / 2f
set(value) { setSize(value * 2f) }
}
28 changes: 28 additions & 0 deletions korge/src/commonMain/kotlin/com/soywiz/korge/view/FastRoundRect.kt
@@ -0,0 +1,28 @@
package com.soywiz.korge.view

import com.soywiz.korge.render.*
import com.soywiz.korim.color.*
import com.soywiz.korma.geom.*

inline fun Container.fastRoundRect(
size: Size,
corners: RectCorners = RectCorners(.1f, .1f, 1f, 1f),
color: RGBA = Colors.WHITE,
callback: @ViewDslMarker FastRoundRect.() -> Unit = {}
) = FastRoundRect(size.widthD, size.heightD, corners).colorMul(color).addTo(this, callback)

open class FastRoundRect(
width: Double = 100.0,
height: Double = 100.0,
corners: RectCorners = RectCorners(.1f, .1f, 1f, 1f)
) : FastRoundRectBase(
width, height, corners, doScale = true
) {
var corners: RectCorners
get() = cornersRatio
set(value) { cornersRatio = value }
override fun renderInternal(ctx: RenderContext) {
cornersRatio = RectCorners(corners.topLeft)
super.renderInternal(ctx)
}
}
@@ -0,0 +1,35 @@
package com.soywiz.korge.view

import com.soywiz.korag.shader.*
import com.soywiz.korge.render.*
import com.soywiz.korma.geom.*

abstract class FastRoundRectBase(
width: Double = 100.0,
height: Double = 100.0,
cornersRatio: RectCorners = RectCorners(.0f, .0f, .0f, .0f),
doScale: Boolean = true
) : ShadedView(PROGRAM, width, height) {
protected var cornersRatio = cornersRatio
protected var doScale = doScale

override fun renderInternal(ctx: RenderContext) {
//colorMul = Colors.RED
this.programUniforms[u_Corners] = cornersRatio
this.programUniforms[u_Scale] = when {
!doScale || width == height -> Point(1f, 1f)
width > height -> Point(width / height, 1.0)
else -> Point(1.0, height / width)
}

super.renderInternal(ctx)
}
companion object {
val u_Corners by Uniform(VarType.Float4)
val u_Scale by Uniform(VarType.Float2)
val PROGRAM = buildShader {
val SDF = SDFShaders
SET(out, v_Col * SDF.opAA(SDF.roundedBox((v_Tex - vec2(.5f, .5f)) * u_Scale, vec2(.5f, .5f) * u_Scale, u_Corners * .5f.lit)))
}
}
}
36 changes: 18 additions & 18 deletions korge/src/commonMain/kotlin/com/soywiz/korge/view/RoundRect.kt
Expand Up @@ -10,27 +10,27 @@ import com.soywiz.korma.geom.vector.*
* Once created, it is added to this receiver [Container].
**/
inline fun Container.roundRect(
width: Int,
height: Int,
rx: Int,
ry: Int = rx,
fill: Paint = Colors.WHITE,
stroke: Paint = Colors.WHITE,
strokeThickness: Double = 0.0,
autoScaling: Boolean = true,
callback: @ViewDslMarker RoundRect.() -> Unit = {}
width: Int,
height: Int,
rx: Int,
ry: Int = rx,
fill: Paint = Colors.WHITE,
stroke: Paint = Colors.WHITE,
strokeThickness: Double = 0.0,
autoScaling: Boolean = true,
callback: @ViewDslMarker RoundRect.() -> Unit = {}
) = roundRect(width.toDouble(), height.toDouble(), rx.toDouble(), ry.toDouble(), fill, stroke, strokeThickness, autoScaling, callback)

inline fun Container.roundRect(
width: Double,
height: Double,
rx: Double,
ry: Double = rx,
fill: Paint = Colors.WHITE,
stroke: Paint = Colors.WHITE,
strokeThickness: Double = 0.0,
autoScaling: Boolean = true,
callback: @ViewDslMarker RoundRect.() -> Unit = {}
width: Double,
height: Double,
rx: Double,
ry: Double = rx,
fill: Paint = Colors.WHITE,
stroke: Paint = Colors.WHITE,
strokeThickness: Double = 0.0,
autoScaling: Boolean = true,
callback: @ViewDslMarker RoundRect.() -> Unit = {}
) = RoundRect(width, height, rx, ry, fill, stroke, strokeThickness, autoScaling).addTo(this, callback)

/**
Expand Down
12 changes: 9 additions & 3 deletions korge/src/commonMain/kotlin/com/soywiz/korge/view/View.kt
Expand Up @@ -399,6 +399,7 @@ abstract class View internal constructor(
this.width = width
this.height = height
}
fun setSize(size: Size) = setSize(size.widthD, size.heightD)

open fun setSizeScaled(width: Double, height: Double) {
this.setSize(
Expand Down Expand Up @@ -960,9 +961,8 @@ abstract class View internal constructor(
return if (this is Stage) this else null
}

fun hitTestLocal(p: Point, direction: HitTestDirection = HitTestDirection.ANY): View? {
return hitTest(localToGlobal(p), direction)
}
fun hitTestLocal(p: Point, direction: HitTestDirection = HitTestDirection.ANY): View? =
hitTest(localToGlobal(p), direction)

override fun hitTestAny(p: Point, direction: HitTestDirection): Boolean =
hitTest(p, direction) != null
Expand Down Expand Up @@ -2043,6 +2043,12 @@ fun <T : View> T.scale(sx: Double, sy: Double = sx): T {
fun <T : View> T.scale(sx: Float, sy: Float = sx): T = scale(sx.toDouble(), sy.toDouble())
fun <T : View> T.scale(sx: Int, sy: Int = sx): T = scale(sx.toDouble(), sy.toDouble())

/** Chainable method returning this that sets [View.colorMul] */
fun <T : View> T.colorMul(color: RGBA): T {
this.colorMul = color
return this
}

/** Chainable method returning this that sets [View.alphaF] */
fun <T : View> T.alpha(alpha: Float): T {
this.alphaF = alpha
Expand Down
Expand Up @@ -14,8 +14,8 @@ class MaskAndBackdropFilterScreenshotJvmTest {
solidRect(width, height, Colors.GREEN)

//val fill1 = LinearGradientPaint(0, 0, 100, 100).add(0.0, Colors.RED).add(1.0, Colors.BLUE)
var maskView = circle(50.0, renderer = GraphicsRenderer.GPU).xy(25, 25).visible(false)
val circle1 = circle(50.0, renderer = GraphicsRenderer.GPU, fill = Colors.RED)
val maskView = fastEllipse(Size(100, 100)).xy(25, 25).visible(false)
val circle1 = fastEllipse(Size(100, 100), color = Colors.RED)
//val circle1 = solidRect(200, 200, Colors.PURPLE)
//.filters(DropshadowFilter())
//.filters(BlurFilter())
Expand All @@ -24,8 +24,7 @@ class MaskAndBackdropFilterScreenshotJvmTest {
//.filters(ColorMatrixFilter(ColorMatrixFilter.GRAYSCALE_MATRIX))
//.mask(solidRect(100, 100, Colors.WHITE).xy(50, 50).visible(false))

roundRect(40, 40, 16, 16).xy(15, 15)
.also { it.renderer = GraphicsRenderer.GPU }
fastRoundRect(Size(40, 40), RectCorners(.5f)).xy(15, 15)
.backdropFilters(ColorMatrixFilter(ColorMatrixFilter.GRAYSCALE_MATRIX))
//.backdropFilters(BlurFilter())

Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 6 additions & 1 deletion korgw/src/commonMain/kotlin/com/soywiz/korag/AGValue.kt
Expand Up @@ -98,6 +98,10 @@ class AGUniformValues(val capacity: Int = 8 * 1024) {
operator fun set(uniform: Uniform, value: Array<MMatrix3D>) { this[uniform].set(value) }
operator fun set(uniform: Uniform, value: Array<FloatArray>) { this[uniform].set(value) }

operator fun set(uniform: Uniform, value: Vector4) { this[uniform].set(value) }
operator fun set(uniform: Uniform, value: Margin) { this[uniform].set(value) }
operator fun set(uniform: Uniform, value: RectCorners) { this[uniform].set(value) }

fun set(uniform: Uniform, v0: Float, v1: Float) { this[uniform].set(v0, v1) }
fun set(uniform: Uniform, v0: Float, v1: Float, v2: Float) { this[uniform].set(v0, v1, v2) }
fun set(uniform: Uniform, v0: Float, v1: Float, v2: Float, v3: Float) { this[uniform].set(v0, v1, v2, v3) }
Expand Down Expand Up @@ -216,7 +220,8 @@ open class AGValue(
fun set(value: Vector4) = set(value.x, value.y, value.z, value.w)
fun set(value: Point) = set(value.x, value.y)
fun set(value: Margin) = set(value.top.toFloat(), value.right.toFloat(), value.bottom.toFloat(), value.left.toFloat())
fun set(value: RectCorners) = set(value.topLeft, value.topRight, value.bottomRight, value.bottomLeft)
fun set(value: RectCorners) = set(value.bottomRight, value.topRight, value.bottomLeft, value.topLeft)

//fun set(value: Matrix4) = tempMatrixLock { set(tempMatrix.also { it[0] = value }) }

fun set(value: RGBA) = set(value.rf, value.gf, value.bf, value.af)
Expand Down