# HG changeset patch # User Sam # Date 1708763752 -25200 # Node ID f9d25bc331b3cb6037e88f43af43dcc97b7c2075 # Parent 7629f85823a48e63e3a8489d5b92750513cb43f9 did: same for panels diff -r 7629f85823a4 -r f9d25bc331b3 semicongine/engine.nim --- a/semicongine/engine.nim Sat Feb 24 14:31:15 2024 +0700 +++ b/semicongine/engine.nim Sat Feb 24 15:35:52 2024 +0700 @@ -225,10 +225,8 @@ func limits*(engine: Engine): VkPhysicalDeviceLimits = engine.gpuDevice().physicalDevice.properties.limits -proc processEventsFor*(engine: Engine, panel: var Panel) = - panel.refresh() - - let hasMouseNow = panel.contains(engine.mousePositionNormalized()) +proc processEvents*(engine: Engine, panel: var Panel) = + let hasMouseNow = panel.contains(engine.mousePositionNormalized, engine.getAspectRatio) # enter/leave events if hasMouseNow: diff -r 7629f85823a4 -r f9d25bc331b3 semicongine/mesh.nim --- a/semicongine/mesh.nim Sat Feb 24 14:31:15 2024 +0700 +++ b/semicongine/mesh.nim Sat Feb 24 15:35:52 2024 +0700 @@ -133,8 +133,8 @@ indices: openArray[array[3, uint32|uint16|uint8]], colors: openArray[Vec4f] = [], uvs: openArray[Vec2f] = [], - transform: Mat4 = Unit4F32, - instanceTransforms: openArray[Mat4] = [Unit4F32], + transform: Mat4 = Unit4, + instanceTransforms: openArray[Mat4] = [Unit4], material = EMPTY_MATERIAL.initMaterialData(), autoResize = true, name: string = "" @@ -189,8 +189,8 @@ positions: openArray[Vec3f], colors: openArray[Vec4f] = [], uvs: openArray[Vec2f] = [], - transform: Mat4 = Unit4F32, - instanceTransforms: openArray[Mat4] = [Unit4F32], + transform: Mat4 = Unit4, + instanceTransforms: openArray[Mat4] = [Unit4], material = EMPTY_MATERIAL.initMaterialData(), name: string = "", ): Mesh = @@ -446,7 +446,7 @@ proc rect*(width = 1'f32, height = 1'f32, color = "ffffffff", material = EMPTY_MATERIAL.initMaterialData()): Mesh = result = Mesh( vertexCount: 4, - instanceTransforms: @[Unit4F32], + instanceTransforms: @[Unit4], indexType: Small, smallIndices: @[[0'u16, 1'u16, 2'u16], [2'u16, 3'u16, 0'u16]], name: &"rect-{instanceCounter}", @@ -467,7 +467,7 @@ proc tri*(width = 1'f32, height = 1'f32, color = "ffffffff", material = EMPTY_MATERIAL.initMaterialData()): Mesh = result = Mesh( vertexCount: 3, - instanceTransforms: @[Unit4F32], + instanceTransforms: @[Unit4], name: &"tri-{instanceCounter}", material: material, ) @@ -484,7 +484,7 @@ assert nSegments >= 3 result = Mesh( vertexCount: 3 + nSegments, - instanceTransforms: @[Unit4F32], + instanceTransforms: @[Unit4], indexType: Small, name: &"circle-{instanceCounter}", material: material, @@ -511,7 +511,7 @@ result = Mesh( vertexCount: int((rows + 1) * (columns + 1)), - instanceTransforms: @[Unit4F32], + instanceTransforms: @[Unit4], indexType: Small, name: &"grid-{instanceCounter}", material: material, @@ -544,7 +544,7 @@ type MeshTree* = ref object mesh*: Mesh - transform*: Mat4 = Unit4F32 + transform*: Mat4 = Unit4 children*: seq[MeshTree] func toStringRec*(tree: MeshTree, theindent = 0): seq[string] = @@ -567,7 +567,7 @@ result.add current.mesh queue.add current.children -proc updateTransforms*(tree: MeshTree, parentTransform = Unit4F32) = +proc updateTransforms*(tree: MeshTree, parentTransform = Unit4) = let currentTransform = parentTransform * tree.transform if not tree.mesh.isNil: tree.mesh.transform = currentTransform diff -r 7629f85823a4 -r f9d25bc331b3 semicongine/panel.nim --- a/semicongine/panel.nim Sat Feb 24 14:31:15 2024 +0700 +++ b/semicongine/panel.nim Sat Feb 24 15:35:52 2024 +0700 @@ -30,10 +30,10 @@ attr[uint16]("materialIndexOut", noInterpolation = true) ], outputs = [attr[Vec4f]("color")], - uniforms = [attr[Vec4f]("color", arrayCount = MAX_PANEL_MATERIALS)], + uniforms = [attr[Vec4f]("color", arrayCount = MAX_PANEL_MATERIALS), attr[float32](ASPECT_RATIO_ATTRIBUTE)], samplers = [attr[Texture]("panelTexture", arrayCount = MAX_PANEL_MATERIALS)], vertexCode = &""" - gl_Position = vec4({POSITION_ATTRIB}, 1.0) * {TRANSFORM_ATTRIB}; + gl_Position = vec4({POSITION_ATTRIB}.x, {POSITION_ATTRIB}.y * Uniforms.{ASPECT_RATIO_ATTRIBUTE}, {POSITION_ATTRIB}.z, 1.0) * {TRANSFORM_ATTRIB}; uvFrag = {UV_ATTRIB}; materialIndexOut = {MATERIALINDEX_ATTRIBUTE}; """, @@ -44,14 +44,11 @@ type Panel* = object - position: Vec2f - size: Vec2f texture: Texture horizontalAlignment: HorizontalAlignment = Center verticalAlignment: VerticalAlignment = Center - aspect_ratio: float32 dirty: bool - mesh: Mesh + mesh*: Mesh # input handling onMouseDown*: proc(panel: var Panel, buttons: set[MouseButton]) onMouseUp*: proc(panel: var Panel, buttons: set[MouseButton]) @@ -61,7 +58,7 @@ hasMouse*: bool proc `$`*(panel: Panel): string = - &"Panel {panel.position} (size {panel.size})" + &"Panel {panel.mesh}" proc refresh*(panel: var Panel) = if not panel.dirty: @@ -69,36 +66,23 @@ var offsetX = case panel.horizontalAlignment - of Left: panel.size.x / 2 + of Left: 0.5 of Center: 0 - of Right: -panel.size.x / 2 + of Right: -0.5 offsetY = case panel.verticalAlignment - of Top: panel.size.y / 2 + of Top: 0.5 of Center: 0 - of Bottom: -panel.size.y / 2 + of Bottom: -0.5 - panel.mesh[POSITION_ATTRIB, 0] = newVec3f( - panel.position.x - panel.size.x / 2 + offsetX, - (panel.position.y - panel.size.y / 2 + offsetY) * panel.aspect_ratio - ) - panel.mesh[POSITION_ATTRIB, 1] = newVec3f( - panel.position.x + panel.size.x / 2 + offsetX, - (panel.position.y - panel.size.y / 2 + offsetY) * panel.aspect_ratio - ) - panel.mesh[POSITION_ATTRIB, 2] = newVec3f( - panel.position.x + panel.size.x / 2 + offsetX, - (panel.position.y + panel.size.y / 2 + offsetY) * panel.aspect_ratio - ) - panel.mesh[POSITION_ATTRIB, 3] = newVec3f( - panel.position.x - panel.size.x / 2 + offsetX, - (panel.position.y + panel.size.y / 2 + offsetY) * panel.aspect_ratio - ) + panel.mesh[POSITION_ATTRIB, 0] = newVec3f(-0.5 + offsetX, -0.5 + offsetY) + panel.mesh[POSITION_ATTRIB, 1] = newVec3f(+0.5 + offsetX, -0.5 + offsetY) + panel.mesh[POSITION_ATTRIB, 2] = newVec3f(+0.5 + offsetX, +0.5 + offsetY) + panel.mesh[POSITION_ATTRIB, 3] = newVec3f(-0.5 + offsetX, +0.5 + offsetY) panel.dirty = false proc initPanel*( - position = newVec2f(), - size = newVec2f(), + transform = Unit4, color = newVec4f(1, 1, 1, 1), texture = EMPTY_TEXTURE, horizontalAlignment = HorizontalAlignment.Center, @@ -111,26 +95,26 @@ ): Panel = result = Panel( - position: position, - size: size, texture: texture, horizontalAlignment: horizontalAlignment, verticalAlignment: verticalAlignment, - aspect_ratio: 1, onMouseDown: onMouseDown, onMouseUp: onMouseUp, onMouseEnter: onMouseEnter, onMouseMove: onMouseMove, onMouseLeave: onMouseLeave, + dirty: true, ) result.mesh = newMesh( + name = &"panel-{instanceCounter}", positions = newSeq[Vec3f](4), indices = @[ [uint16(0), uint16(1), uint16(2)], [uint16(2), uint16(3), uint16(0)], ], - uvs = @[newVec2f(0, 1), newVec2f(1, 1), newVec2f(1, 0), newVec2f(0, 0)], name = &"panel-{instanceCounter}" + uvs = @[newVec2f(0, 1), newVec2f(1, 1), newVec2f(1, 0), newVec2f(0, 0)], + transform = transform ) result.mesh[].renameAttribute("position", POSITION_ATTRIB) result.mesh[].renameAttribute("uv", UV_ATTRIB) @@ -142,32 +126,12 @@ inc instanceCounter result.refresh() -proc position*(panel: Panel): Vec2f = - panel.position -proc `position=`*(panel: var Panel, value: Vec2f) = - if value != panel.position: - panel.position = value - panel.dirty = true - proc color*(panel: Panel): Vec4f = panel.mesh.material["color", 0, Vec4f] proc `color=`*(panel: var Panel, value: Vec4f) = if value != panel.color: panel.mesh.material["color", 0] = value -proc transform*(panel: Panel): Mat4 = - panel.mesh.transform -proc `transform=`*(panel: var Panel, value: Mat4) = - if value != panel.transform: - panel.mesh.transform = value - -proc size*(panel: Panel): Vec2f = - panel.size -proc `size=`*(panel: var Panel, value: Vec2f) = - if value != panel.size: - panel.size = value - panel.dirty = true - proc horizontalAlignment*(panel: Panel): HorizontalAlignment = panel.horizontalAlignment proc `horizontalAlignment=`*(panel: var Panel, value: HorizontalAlignment) = @@ -182,20 +146,13 @@ panel.verticalAlignment = value panel.dirty = true -proc aspect_ratio*(panel: Panel): float32 = - panel.aspect_ratio -proc `aspect_ratio=`*(panel: var Panel, value: float32) = - if value != panel.aspect_ratio: - panel.aspect_ratio = value - panel.dirty = true - -proc contains*(panel: Panel, p: Vec2f): bool = - let cursor = panel.mesh.transform * p.toVec3 - let p1 = panel.mesh[POSITION_ATTRIB, 0, Vec3f] - let p2 = panel.mesh[POSITION_ATTRIB, 2, Vec3f] +proc contains*(panel: Panel, p: Vec2f, aspectRatio: float32): bool = let + cursor = panel.mesh.transform.inversed * p.toVec3 + p1 = panel.mesh[POSITION_ATTRIB, 0, Vec3f] + p2 = panel.mesh[POSITION_ATTRIB, 2, Vec3f] left = min(p1.x, p2.x) right = max(p1.x, p2.x) - top = min(p1.y, p2.y) - bottom = max(p1.y, p2.y) + top = min(p1.y * aspectRatio, p2.y * aspectRatio) + bottom = max(p1.y * aspectRatio, p2.y * aspectRatio) return left <= cursor.x and cursor.x <= right and top <= cursor.y and cursor.y <= bottom diff -r 7629f85823a4 -r f9d25bc331b3 tests/test_panel.nim --- a/tests/test_panel.nim Sat Feb 24 14:31:15 2024 +0700 +++ b/tests/test_panel.nim Sat Feb 24 15:35:52 2024 +0700 @@ -12,9 +12,11 @@ counter.dec counterText.text = $counter proc enter(panel: var Panel) = - panel.size = newVec2f(0.22, 0.22) + panel.mesh.transform = panel.mesh.transform * scale(1.05, 1.05) + panel.color = newVec4f(1, 0, 0, 0.3) proc leave(panel: var Panel) = - panel.size = newVec2f(0.2, 0.2) + panel.mesh.transform = panel.mesh.transform * scale(1 / 1.05, 1 / 1.05) + panel.color = newVec4f(1, 0, 0, 0.5) proc main() = # setup engine @@ -29,12 +31,12 @@ font = loadFont("DejaVuSans.ttf", lineHeightPixels = 210'f32) scene = Scene(name: "main") origin = initPanel( - size = newVec2f(0.005, 0.005), + transform = scale(0.005, 0.005), color = newVec4f(1, 1, 1, 1), texture = Texture(isGrayscale: false, colorImage: newImage[RGBAPixel](3, 3, [T, B, T, B, B, B, T, B, T]), sampler: NEAREST_SAMPLER), ) - panel = initPanel( - size = newVec2f(0.2, 0.2), + button = initPanel( + transform = translate(0.2, 0.1) * scale(0.3, 0.1), color = newVec4f(1, 0, 0, 0.5), onMouseDown = click, onMouseEnter = enter, @@ -52,46 +54,39 @@ F6: Bottom Mouse: Left click: Increase counter - Right click: Decrease counter""", scale = 0.0002, position = newVec2f(-0.9, -0.9), horizontalAlignment = Left, verticalAlignment = Top) + Right click: Decrease counter""".toRunes, horizontalAlignment = Left, verticalAlignment = Top, transform = translate(-0.9, -0.9) * scale(0.0002, 0.0002)) - counterText = font.initText($counter, maxLen = 99, scale = 0.0004) + counterText = font.initText(($counter).toRunes, maxLen = 99, transform = translate(0.2, 0.1) * scale(0.0004, 0.0004)) scene.add counterText - scene.add panel + scene.add button scene.add help_text scene.add origin engine.loadScene(scene) while engine.updateInputs() == Running and not engine.keyIsDown(Escape): - if engine.windowWasResized(): - var winSize = engine.getWindow().size - panel.aspect_ratio = winSize[0] / winSize[1] - counterText.aspect_ratio = winSize[0] / winSize[1] - origin.aspect_ratio = winSize[0] / winSize[1] - help_text.aspect_ratio = winSize[0] / winSize[1] - if engine.keyWasPressed(F1): - panel.horizontalAlignment = Left + button.horizontalAlignment = Left counterText.horizontalAlignment = Left elif engine.keyWasPressed(F2): - panel.horizontalAlignment = Center + button.horizontalAlignment = Center counterText.horizontalAlignment = Center elif engine.keyWasPressed(F3): - panel.horizontalAlignment = Right + button.horizontalAlignment = Right counterText.horizontalAlignment = Right elif engine.keyWasPressed(F4): - panel.verticalAlignment = Top + button.verticalAlignment = Top counterText.verticalAlignment = Top elif engine.keyWasPressed(F5): - panel.verticalAlignment = Center + button.verticalAlignment = Center counterText.verticalAlignment = Center elif engine.keyWasPressed(F6): - panel.verticalAlignment = Bottom + button.verticalAlignment = Bottom counterText.verticalAlignment = Bottom - engine.processEventsFor(panel) + engine.processEvents(button) - panel.refresh() + button.refresh() counterText.refresh() origin.refresh() help_text.refresh()