Skip to content

Commit 0bebd02

Browse files
committed
port fixes
1 parent 80316fc commit 0bebd02

File tree

1 file changed

+99
-85
lines changed
  • modules/ui/src/main/kotlin/org/polyfrost/oneconfig/api/ui/v1/internal

1 file changed

+99
-85
lines changed

modules/ui/src/main/kotlin/org/polyfrost/oneconfig/api/ui/v1/internal/GLRendererImpl.kt

Lines changed: 99 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@file:Suppress("UnstableApiUsage", "INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
2+
13
package org.polyfrost.oneconfig.api.ui.v1.internal
24

35
import dev.deftu.omnicore.api.client.render.GlCapabilities
@@ -41,14 +43,36 @@ private const val MAX_BATCH = 1024
4143

4244
private val EMPTY_ROW = floatArrayOf(0f, 0f, 0f, 0f)
4345
private val NO_UV = floatArrayOf(-1f, -1f, 1f, 1f)
46+
private val IDENTITY = floatArrayOf(
47+
1f, 0f, 0f,
48+
0f, 1f, 0f,
49+
0f, 0f, 1f
50+
)
51+
52+
private fun FloatArray.isIdentity(): Boolean {
53+
return this[0] == 1f && this[1] == 0f && this[2] == 0f &&
54+
this[3] == 0f && this[4] == 1f && this[5] == 0f &&
55+
this[6] == 0f && this[7] == 0f && this[8] == 1f
56+
}
57+
58+
@kotlin.internal.InlineOnly
59+
private inline fun FloatArray.set(other: FloatArray) {
60+
System.arraycopy(other, 0, this, 0, 9)
61+
}
62+
63+
@kotlin.internal.InlineOnly
64+
private inline fun FloatArray.setThenClear(other: FloatArray) {
65+
System.arraycopy(other, 0, this, 0, 9)
66+
System.arraycopy(IDENTITY, 0, other, 0, 9)
67+
}
4468

45-
@Suppress("UnstableApiUsage", "INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
4669
class GLRendererImpl(private val nsvg: NanoSvgApi, private val stb: StbApi) : Renderer, RendererExt {
4770

4871
private val buffer = BufferUtils.createFloatBuffer(MAX_BATCH * STRIDE)
4972
private val scissorStack = IntArray(MAX_UI_DEPTH * 4)
50-
private val transformStack = ArrayList<FloatArray>(MAX_UI_DEPTH)
73+
private val transformStack = Array(MAX_UI_DEPTH) { FloatArray(9) }
5174
private val fonts = HashMap<Font, FontAtlas>()
75+
private val init get() = program != 0
5276

5377
// lateinit
5478
private var mipmapMode = 0
@@ -75,6 +99,7 @@ class GLRendererImpl(private val nsvg: NanoSvgApi, private val stb: StbApi) : Re
7599
// Current batch state
76100
private var count = 0
77101
private var curTex = 0
102+
private var transformDepth = 0
78103
private var curScissor = 0
79104
private var transform = floatArrayOf(
80105
1f, 0f, 0f,
@@ -86,7 +111,6 @@ class GLRendererImpl(private val nsvg: NanoSvgApi, private val stb: StbApi) : Re
86111
private var pixelRatio = 1f
87112
private var alphaCap = 1f
88113
private var popFlushNeeded = false
89-
private val init get() = program != 0
90114

91115
private var slotX = 0
92116
private var slotY = 0
@@ -128,14 +152,19 @@ class GLRendererImpl(private val nsvg: NanoSvgApi, private val stb: StbApi) : Re
128152
float rRight = mix(r.z, r.y, py); // bottom-right / top-right
129153
float radius = mix(rLeft, rRight, px);
130154
131-
vec2 d = abs(p) - b + vec2(radius);
132-
vec2 dClamped = max(d, vec2(0.0));
133-
return length(dClamped) - radius + min(max(d.x, d.y), 0.0);
155+
vec2 q = abs(p) - (b - vec2(radius));
156+
return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - radius;
134157
}
135158
136159
float hollowRoundedBoxSDF(vec2 p, vec2 b, vec4 r, float thickness) {
137-
float dist = roundedBoxSDF(p, b, r);
138-
return abs(dist) - thickness * 0.5;
160+
float outer = roundedBoxSDF(p, b + vec2(0.2), r);
161+
float inner = roundedBoxSDF(p, b - vec2(thickness), max(r - vec4(thickness), 0.0));
162+
return max(outer, -inner);
163+
}
164+
165+
float roundBoxSDF(vec2 p, vec2 halfSize, float radius) {
166+
vec2 q = abs(p) - (halfSize - vec2(radius));
167+
return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - radius;
139168
}
140169
141170
void main() {
@@ -152,20 +181,19 @@ class GLRendererImpl(private val nsvg: NanoSvgApi, private val stb: StbApi) : Re
152181
col = (vThickness == -1.0) ? vec4(col.rgb, col.a * texColor.r) : col * texColor;
153182
}
154183
else if (vThickness == -2.0) { // linear gradient, vUV as start and vUV2 as end
155-
vec2 dir = normalize(vUV2 - vUV);
156-
float t = dot((p + halfSize) - vUV, dir) / length(vUV2 - vUV);
157-
t = clamp(t, 0.0, 1.0);
184+
vec2 dir = vUV2 - vUV;
185+
float len = length(dir);
186+
float t = clamp(dot((p + halfSize) - vUV, dir / len) / len, 0.0, 1.0);
158187
col = mix(vColor0, vColor1, t);
159188
}
160189
else if (vThickness == -3.0) { // radial gradient, vUV as center and vUV2.x as radius
161190
float dist = length(p + halfSize - vUV);
162-
float t = (dist - vUV2.x) / (vUV2.y - vUV2.x);
163-
t = clamp(t, 0.0, 1.0);
191+
float t = clamp((dist - vUV2.x) / (vUV2.y - vUV2.x), 0.0, 1.0);
164192
col = mix(vColor0, vColor1, t);
165193
}
166194
else if (vThickness == -4.0) { // box gradient, vUV.x as radius and vUV.y as feather
167-
float dist = roundedBoxSDF(p, halfSize - vec2(vUV.x), vec4(vUV.x));
168-
float t = clamp(dist / vUV.y, 0.0, 1.0);
195+
float dist = roundBoxSDF(p, halfSize, vUV.x);
196+
float t = clamp((dist + vUV.y * 0.5) / vUV.y, 0.0, 1.0);
169197
col = mix(vColor0, vColor1, t);
170198
}
171199
@@ -380,7 +408,8 @@ class GLRendererImpl(private val nsvg: NanoSvgApi, private val stb: StbApi) : Re
380408
alphaCap = 1f
381409
count = 0
382410
buffer.clear()
383-
loadIdentity()
411+
transform.set(IDENTITY)
412+
transformDepth = 0
384413
val prevProg = glGetInteger(GL_CURRENT_PROGRAM)
385414
glUseProgram(program)
386415
glUniform2f(uWindow, width, height)
@@ -596,7 +625,7 @@ class GLRendererImpl(private val nsvg: NanoSvgApi, private val stb: StbApi) : Re
596625
if (count >= MAX_BATCH) {
597626
flush()
598627
}
599-
val glyph = fAtlas.get(c) ?: continue
628+
val glyph = fAtlas.get(c)
600629
buffer.put(penX + glyph.xOff * scaleFactor).put(penY + glyph.yOff * scaleFactor)
601630
.put(glyph.width * scaleFactor).put(glyph.height * scaleFactor)
602631
buffer.put(EMPTY_ROW) // zero radii
@@ -697,15 +726,17 @@ class GLRendererImpl(private val nsvg: NanoSvgApi, private val stb: StbApi) : Re
697726

698727
override fun push() {
699728
if (transform.isIdentity()) return
700-
transformStack.add(transform.copyOf())
729+
transformStack[transformDepth++].set(transform)
701730
}
702731

703732
override fun pop() {
704733
if (transform.isIdentity()) return
705734
flush()
706-
if (transformStack.isEmpty()) {
707-
loadIdentity()
708-
} else transform = transformStack.removeLast()
735+
if (transformDepth == 0) {
736+
transform.set(IDENTITY)
737+
} else {
738+
transform.setThenClear(transformStack[--transformDepth])
739+
}
709740
popFlushNeeded = true
710741
}
711742

@@ -763,20 +794,6 @@ class GLRendererImpl(private val nsvg: NanoSvgApi, private val stb: StbApi) : Re
763794
popFlushNeeded = true
764795
}
765796

766-
private fun FloatArray.isIdentity(): Boolean {
767-
return this[0] == 1f && this[1] == 0f && this[2] == 0f &&
768-
this[3] == 0f && this[4] == 1f && this[5] == 0f &&
769-
this[6] == 0f && this[7] == 0f && this[8] == 1f
770-
}
771-
772-
private fun loadIdentity() {
773-
val transform = transform
774-
transform[0] = 1f; transform[1] = 0f; transform[2] = 0f
775-
transform[3] = 0f; transform[4] = 1f; transform[5] = 0f
776-
transform[6] = 0f; transform[7] = 0f; transform[8] = 1f
777-
this.transform = transform
778-
}
779-
780797
override fun initImage(image: PolyImage, size: Vec2) {
781798
if (image.initialized) return
782799
val w = IntArray(1)
@@ -800,27 +817,26 @@ class GLRendererImpl(private val nsvg: NanoSvgApi, private val stb: StbApi) : Re
800817
h[0] / ATLAS_SIZE.toFloat()
801818
)
802819

803-
synchronized(this) {
804-
val prevActive = glGetInteger(GL_ACTIVE_TEXTURE)
805-
val prevTex = glGetInteger(GL_TEXTURE_BINDING_2D)
806-
glActiveTexture(GL_TEXTURE0)
807-
glBindTexture(GL_TEXTURE_2D, atlas)
808-
glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
809-
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)
810-
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0)
811-
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0)
812-
glTexSubImage2D(GL_TEXTURE_2D, 0, slotX, slotY, w[0], h[0], GL_RGBA, GL_UNSIGNED_BYTE, d)
813-
when (mipmapMode) {
814-
1 -> org.lwjgl.opengl.GL30.glGenerateMipmap(GL_TEXTURE_2D)
815-
2 -> org.lwjgl.opengl.EXTFramebufferObject.glGenerateMipmapEXT(GL_TEXTURE_2D)
816-
}
817-
glBindTexture(GL_TEXTURE_2D, prevTex)
818-
glActiveTexture(prevActive)
820+
val prevActive = glGetInteger(GL_ACTIVE_TEXTURE)
821+
val prevTex = glGetInteger(GL_TEXTURE_BINDING_2D)
822+
glActiveTexture(GL_TEXTURE0)
823+
glBindTexture(GL_TEXTURE_2D, atlas)
824+
glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
825+
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)
826+
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0)
827+
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0)
828+
glTexSubImage2D(GL_TEXTURE_2D, 0, slotX, slotY, w[0], h[0], GL_RGBA, GL_UNSIGNED_BYTE, d)
829+
when (mipmapMode) {
830+
1 -> org.lwjgl.opengl.GL30.glGenerateMipmap(GL_TEXTURE_2D)
831+
2 -> org.lwjgl.opengl.EXTFramebufferObject.glGenerateMipmapEXT(GL_TEXTURE_2D)
819832
}
833+
glBindTexture(GL_TEXTURE_2D, prevTex)
834+
glActiveTexture(prevActive)
835+
820836
if (image.type == PolyImage.Type.Raster) stb.image_free(d)
821837

822-
slotX += w[0]
823-
if (h[0] > atlasRowHeight) atlasRowHeight = h[0]
838+
slotX += w[0] + 1
839+
if (h[0] + 1 > atlasRowHeight) atlasRowHeight = h[0] + 1
824840
image.reportInit()
825841
}
826842

@@ -882,7 +898,6 @@ class GLRendererImpl(private val nsvg: NanoSvgApi, private val stb: StbApi) : Re
882898
if (quadVbo != 0) glDeleteBuffers(quadVbo)
883899
if (instancedVbo != 0) glDeleteBuffers(instancedVbo)
884900
if (atlas != 0) glDeleteTextures(atlas)
885-
transformStack.clear()
886901
fonts.clear()
887902
buffer.clear()
888903
}
@@ -985,44 +1000,43 @@ class GLRendererImpl(private val nsvg: NanoSvgApi, private val stb: StbApi) : Re
9851000
stb.free(packed)
9861001
stb.free(range)
9871002

988-
synchronized(this@GLRendererImpl) {
989-
val prevActive = glGetInteger(GL_ACTIVE_TEXTURE)
990-
val prevTex = glGetInteger(GL_TEXTURE_BINDING_2D)
991-
glActiveTexture(GL_TEXTURE0)
992-
glBindTexture(GL_TEXTURE_2D, atlas)
993-
glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
994-
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)
995-
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0)
996-
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0)
997-
// can't write to the alpha channel in GL3 core! lol haha
998-
glTexSubImage2D(
999-
GL_TEXTURE_2D,
1000-
0,
1001-
sx,
1002-
sy,
1003-
FONT_MAX_BITMAP_W,
1004-
FONT_MAX_BITMAP_H,
1005-
GL_RED,
1006-
GL_UNSIGNED_BYTE,
1007-
bitMap
1008-
)
1009-
when (mipmapMode) {
1010-
1 -> org.lwjgl.opengl.GL30.glGenerateMipmap(GL_TEXTURE_2D)
1011-
2 -> org.lwjgl.opengl.EXTFramebufferObject.glGenerateMipmapEXT(GL_TEXTURE_2D)
1012-
}
1013-
glBindTexture(GL_TEXTURE_2D, prevTex)
1014-
glActiveTexture(prevActive)
1003+
val prevActive = glGetInteger(GL_ACTIVE_TEXTURE)
1004+
val prevTex = glGetInteger(GL_TEXTURE_BINDING_2D)
1005+
glActiveTexture(GL_TEXTURE0)
1006+
glBindTexture(GL_TEXTURE_2D, atlas)
1007+
glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
1008+
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)
1009+
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0)
1010+
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0)
1011+
// can't write to the alpha channel in GL3 core! lol haha
1012+
glTexSubImage2D(
1013+
GL_TEXTURE_2D,
1014+
0,
1015+
sx,
1016+
sy,
1017+
FONT_MAX_BITMAP_W,
1018+
FONT_MAX_BITMAP_H,
1019+
GL_RED,
1020+
GL_UNSIGNED_BYTE,
1021+
bitMap
1022+
)
1023+
when (mipmapMode) {
1024+
1 -> org.lwjgl.opengl.GL30.glGenerateMipmap(GL_TEXTURE_2D)
1025+
2 -> org.lwjgl.opengl.EXTFramebufferObject.glGenerateMipmapEXT(GL_TEXTURE_2D)
10151026
}
1016-
slotX += totalSizeX
1017-
atlasRowHeight = maxOf(atlasRowHeight, totalSizeY)
1027+
glBindTexture(GL_TEXTURE_2D, prevTex)
1028+
glActiveTexture(prevActive)
1029+
1030+
slotX += totalSizeX + 1
1031+
atlasRowHeight = maxOf(atlasRowHeight, totalSizeY + 1)
10181032
}
10191033

10201034
fun measure(text: String, fontSize: Float): Vec2 {
10211035
var width = 0f
10221036
// var height = 0f
10231037
val scaleFactor = fontSize / this.renderedSize
10241038
for (c in text) {
1025-
val g = get(c) ?: continue
1039+
val g = get(c)
10261040
width += g.xAdvance * scaleFactor
10271041
// height = maxOf(height, g.height + g.offsetY)
10281042
}
@@ -1031,7 +1045,7 @@ class GLRendererImpl(private val nsvg: NanoSvgApi, private val stb: StbApi) : Re
10311045

10321046
@Suppress("DEPRECATION")
10331047
@kotlin.internal.InlineOnly
1034-
inline fun get(char: Char) = if (char.toInt() in 32..32+95) glyphs[(char.toInt() - 32)] else null
1048+
inline fun get(char: Char) = if (char.toInt() in 32..32 + 95) glyphs[(char.toInt() - 32)] else glyphs['?'.toInt()]
10351049
}
10361050

10371051
@kotlin.internal.InlineOnly

0 commit comments

Comments
 (0)