comparison semiconginev2/old/panel.nim @ 1218:56781cc0fc7c compiletime-tests

did: renamge main package
author sam <sam@basx.dev>
date Wed, 17 Jul 2024 21:01:37 +0700
parents semicongine/old/panel.nim@a3eb305bcac2
children
comparison
equal deleted inserted replaced
1217:f819a874058f 1218:56781cc0fc7c
1 import std/strformat
2 import std/tables
3
4 import ./core
5 import ./mesh
6 import ./material
7 import ./vulkan/shader
8 import ./events
9
10 const
11 # font shader
12 SHADER_ATTRIB_PREFIX = "semicon_panel_"
13 MAX_PANEL_MATERIALS = 10
14 POSITION_ATTRIB = SHADER_ATTRIB_PREFIX & "position"
15 UV_ATTRIB = SHADER_ATTRIB_PREFIX & "uv"
16 PANEL_MATERIAL_TYPE* = MaterialType(
17 name: "default-panel-material-type",
18 vertexAttributes: {POSITION_ATTRIB: Vec3F32, UV_ATTRIB: Vec2F32}.toTable,
19 instanceAttributes: {TRANSFORM_ATTRIB: Mat4F32, MATERIALINDEX_ATTRIBUTE: UInt16}.toTable,
20 attributes: {"panelTexture": TextureType, "color": Vec4F32}.toTable,
21 )
22 PANEL_SHADER* = CreateShaderConfiguration(
23 name = "panel shader",
24 inputs = [
25 Attr[Mat4](TRANSFORM_ATTRIB, memoryPerformanceHint = PreferFastWrite, perInstance = true),
26 Attr[Vec3f](POSITION_ATTRIB, memoryPerformanceHint = PreferFastWrite),
27 Attr[Vec2f](UV_ATTRIB, memoryPerformanceHint = PreferFastWrite),
28 Attr[uint16](MATERIALINDEX_ATTRIBUTE, memoryPerformanceHint = PreferFastRead, perInstance = true),
29 ],
30 intermediates = [
31 Attr[Vec2f]("uvFrag"),
32 Attr[uint16]("materialIndexOut", noInterpolation = true)
33 ],
34 outputs = [Attr[Vec4f]("color")],
35 uniforms = [Attr[Vec4f]("color", arrayCount = MAX_PANEL_MATERIALS), Attr[float32](ASPECT_RATIO_ATTRIBUTE)],
36 samplers = [Attr[Texture]("panelTexture", arrayCount = MAX_PANEL_MATERIALS)],
37 vertexCode = &"""
38 gl_Position = vec4({POSITION_ATTRIB}.x, {POSITION_ATTRIB}.y * Uniforms.{ASPECT_RATIO_ATTRIBUTE}, {POSITION_ATTRIB}.z, 1.0) * {TRANSFORM_ATTRIB};
39 uvFrag = {UV_ATTRIB};
40 materialIndexOut = {MATERIALINDEX_ATTRIBUTE};
41 """,
42 fragmentCode = &"""color = Uniforms.color[materialIndexOut] * texture(panelTexture[materialIndexOut], uvFrag);"""
43 )
44
45 var instanceCounter = 0
46
47 type
48 Panel* = object
49 texture: Texture
50 horizontalAlignment: HorizontalAlignment = Center
51 verticalAlignment: VerticalAlignment = Center
52 dirty: bool
53 mesh*: Mesh
54 # input handling
55 onMouseDown*: proc(panel: var Panel, buttons: set[MouseButton])
56 onMouseUp*: proc(panel: var Panel, buttons: set[MouseButton])
57 onMouseEnter*: proc(panel: var Panel)
58 onMouseMove*: proc(panel: var Panel)
59 onMouseLeave*: proc(panel: var Panel)
60 hasMouse*: bool
61
62 proc `$`*(panel: Panel): string =
63 &"Panel {panel.mesh}"
64
65 proc Refresh*(panel: var Panel) =
66 if not panel.dirty:
67 return
68
69 var
70 offsetX = case panel.horizontalAlignment
71 of Left: 0.5
72 of Center: 0
73 of Right: -0.5
74 offsetY = case panel.verticalAlignment
75 of Top: 0.5
76 of Center: 0
77 of Bottom: -0.5
78
79 panel.mesh[POSITION_ATTRIB, 0] = NewVec3f(-0.5 + offsetX, -0.5 + offsetY)
80 panel.mesh[POSITION_ATTRIB, 1] = NewVec3f(+0.5 + offsetX, -0.5 + offsetY)
81 panel.mesh[POSITION_ATTRIB, 2] = NewVec3f(+0.5 + offsetX, +0.5 + offsetY)
82 panel.mesh[POSITION_ATTRIB, 3] = NewVec3f(-0.5 + offsetX, +0.5 + offsetY)
83
84 panel.dirty = false
85
86 proc InitPanel*(
87 transform = Unit4,
88 color = NewVec4f(1, 1, 1, 1),
89 texture = EMPTY_TEXTURE,
90 horizontalAlignment = HorizontalAlignment.Center,
91 verticalAlignment = VerticalAlignment.Center,
92 onMouseDown: proc(panel: var Panel, buttons: set[MouseButton]) = nil,
93 onMouseUp: proc(panel: var Panel, buttons: set[MouseButton]) = nil,
94 onMouseEnter: proc(panel: var Panel) = nil,
95 onMouseMove: proc(panel: var Panel) = nil,
96 onMouseLeave: proc(panel: var Panel) = nil,
97 ): Panel =
98
99 result = Panel(
100 texture: texture,
101 horizontalAlignment: horizontalAlignment,
102 verticalAlignment: verticalAlignment,
103 onMouseDown: onMouseDown,
104 onMouseUp: onMouseUp,
105 onMouseEnter: onMouseEnter,
106 onMouseMove: onMouseMove,
107 onMouseLeave: onMouseLeave,
108 dirty: true,
109 )
110
111 result.mesh = NewMesh(
112 name = &"panel-{instanceCounter}",
113 positions = newSeq[Vec3f](4),
114 indices = @[
115 [uint16(0), uint16(1), uint16(2)],
116 [uint16(2), uint16(3), uint16(0)],
117 ],
118 uvs = @[NewVec2f(0, 1), NewVec2f(1, 1), NewVec2f(1, 0), NewVec2f(0, 0)],
119 transform = transform
120 )
121 result.mesh[].RenameAttribute("position", POSITION_ATTRIB)
122 result.mesh[].RenameAttribute("uv", UV_ATTRIB)
123 result.mesh.material = InitMaterialData(
124 theType = PANEL_MATERIAL_TYPE,
125 name = "Panel material",
126 attributes = {"panelTexture": InitDataList(@[texture]), "color": InitDataList(@[color])},
127 )
128 inc instanceCounter
129 result.Refresh()
130
131 proc Color*(panel: Panel): Vec4f =
132 panel.mesh.material["color", 0, Vec4f]
133 proc `color=`*(panel: var Panel, value: Vec4f) =
134 if value != panel.mesh.material["color", 0, Vec4f]:
135 panel.mesh.material["color", 0] = value
136
137 proc HorizontalAlignment*(panel: Panel): HorizontalAlignment =
138 panel.horizontalAlignment
139 proc `horizontalAlignment=`*(panel: var Panel, value: HorizontalAlignment) =
140 if value != panel.horizontalAlignment:
141 panel.horizontalAlignment = value
142 panel.dirty = true
143
144 proc VerticalAlignment*(panel: Panel): VerticalAlignment =
145 panel.verticalAlignment
146 proc `verticalAlignment=`*(panel: var Panel, value: VerticalAlignment) =
147 if value != panel.verticalAlignment:
148 panel.verticalAlignment = value
149 panel.dirty = true
150
151 proc Contains*(panel: Panel, p: Vec2f, aspectRatio: float32): bool =
152 let
153 cursor = panel.mesh.transform.Inversed * p.ToVec3
154 p1 = panel.mesh[POSITION_ATTRIB, 0, Vec3f]
155 p2 = panel.mesh[POSITION_ATTRIB, 2, Vec3f]
156 left = min(p1.x, p2.x)
157 right = max(p1.x, p2.x)
158 top = min(p1.y * aspectRatio, p2.y * aspectRatio)
159 bottom = max(p1.y * aspectRatio, p2.y * aspectRatio)
160 return left <= cursor.x and cursor.x <= right and top <= cursor.y and cursor.y <= bottom