Use local context instead of global
This commit is contained in:
parent
734732fbbd
commit
77e390e9be
6 changed files with 302 additions and 274 deletions
|
|
@ -18,34 +18,34 @@ proc currentSourceDir*(): string {.inline.} =
|
||||||
|
|
||||||
# Config
|
# Config
|
||||||
|
|
||||||
proc drawLabel*(text: string, x, y, w, h: float) =
|
proc drawLabel*(vg: Context, text: string, x, y, w, h: float) =
|
||||||
nanovg.setFontSize(50.0)
|
vg.setFontSize(50.0)
|
||||||
nanovg.setFont("sans")
|
vg.setFont("sans")
|
||||||
nanovg.setFillColor(1.0, 1.0, 1.0, 1.0)
|
vg.setFillColor(1.0, 1.0, 1.0, 1.0)
|
||||||
|
|
||||||
nanovg.textAlign("left middle")
|
vg.textAlign("left middle")
|
||||||
nanovg.text(text, x, y+h*0.5)
|
vg.text(text, x, y+h*0.5)
|
||||||
|
|
||||||
proc drawWindow*(title: string, x, y, w, h: float) =
|
proc drawWindow*(vg: Context, title: string, x, y, w, h: float) =
|
||||||
let cornerRadius = 3.0
|
let cornerRadius = 3.0
|
||||||
withState:
|
withState(vg):
|
||||||
nanovg.beginPath()
|
vg.beginPath()
|
||||||
nanovg.pathRoundedRect(x, y, w, h, cornerRadius)
|
vg.pathRoundedRect(x, y, w, h, cornerRadius)
|
||||||
#nanovg.setFillColor(rgba(255,255,255,192))
|
#vg.setFillColor(rgba(255,255,255,192))
|
||||||
nanovg.setFillColor(rgba(28,30,34,192))
|
vg.setFillColor(rgba(28,30,34,192))
|
||||||
nanovg.pathFill()
|
vg.pathFill()
|
||||||
|
|
||||||
nanovg.setFontSize(30.0)
|
vg.setFontSize(30.0)
|
||||||
nanovg.setFont("sans")
|
vg.setFont("sans")
|
||||||
nanovg.textAlign("center middle")
|
vg.textAlign("center middle")
|
||||||
|
|
||||||
nanovg.setFontBlur(2)
|
vg.setFontBlur(2)
|
||||||
nanovg.setFillColor(rgba(0,0,0,128))
|
vg.setFillColor(rgba(0,0,0,128))
|
||||||
nanovg.text(title, x+w/2, y+16+1)
|
vg.text(title, x+w/2, y+16+1)
|
||||||
|
|
||||||
nanovg.setFontBlur(0)
|
vg.setFontBlur(0)
|
||||||
nanovg.setFillColor(rgba(220,220,220,160))
|
vg.setFillColor(rgba(220,220,220,160))
|
||||||
nanovg.text(title, x+w/2,y+16)
|
vg.text(title, x+w/2,y+16)
|
||||||
|
|
||||||
proc isBlack*(color: Color): bool =
|
proc isBlack*(color: Color): bool =
|
||||||
result = true
|
result = true
|
||||||
|
|
@ -93,8 +93,8 @@ proc cpToUtf8*(code: int): string =
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
proc drawButton*(text: string, x, y, width, height: float) =
|
proc drawButton*(vg: Context, text: string, x, y, width, height: float) =
|
||||||
let bg = linearGradient(
|
let bg = vg.linearGradient(
|
||||||
x, y, x, y+height,
|
x, y, x, y+height,
|
||||||
rgba(255, 255, 255, 16),
|
rgba(255, 255, 255, 16),
|
||||||
rgba(100, 100, 100, 16)
|
rgba(100, 100, 100, 16)
|
||||||
|
|
@ -109,28 +109,28 @@ proc drawButton*(text: string, x, y, width, height: float) =
|
||||||
let drawShadow = true
|
let drawShadow = true
|
||||||
|
|
||||||
if drawShadow:
|
if drawShadow:
|
||||||
nanovg.beginPath()
|
vg.beginPath()
|
||||||
nanovg.pathRoundedRect(x+1+shadowOffset, y+1+shadowOffset, width-2, height-2, radius)
|
vg.pathRoundedRect(x+1+shadowOffset, y+1+shadowOffset, width-2, height-2, radius)
|
||||||
nanovg.setFillColor(shadowColor)
|
vg.setFillColor(shadowColor)
|
||||||
nanovg.pathFill()
|
vg.pathFill()
|
||||||
|
|
||||||
nanovg.beginPath()
|
vg.beginPath()
|
||||||
nanovg.pathRoundedRect(x+1, y+1, width-2, height-2, radius)
|
vg.pathRoundedRect(x+1, y+1, width-2, height-2, radius)
|
||||||
nanovg.setFillColor(color)
|
vg.setFillColor(color)
|
||||||
nanovg.pathFill()
|
vg.pathFill()
|
||||||
|
|
||||||
nanovg.setFillPaint(bg)
|
vg.setFillPaint(bg)
|
||||||
nanovg.pathFill()
|
vg.pathFill()
|
||||||
|
|
||||||
nanovg.beginPath()
|
vg.beginPath()
|
||||||
nanovg.pathMoveTo(x+radius, y+lightWidth+1)
|
vg.pathMoveTo(x+radius, y+lightWidth+1)
|
||||||
nanovg.setStrokeWidth(lightWidth)
|
vg.setStrokeWidth(lightWidth)
|
||||||
nanovg.setStrokeColor(highlightColor)
|
vg.setStrokeColor(highlightColor)
|
||||||
nanovg.pathLineTo(x+width-(radius), y+lightWidth+1)
|
vg.pathLineTo(x+width-(radius), y+lightWidth+1)
|
||||||
nanovg.pathStroke()
|
vg.pathStroke()
|
||||||
|
|
||||||
|
|
||||||
proc drawButton*(preicon: string, text: string, x, y, w, h: float, color: Color) =
|
proc drawButton*(vg: Context, preicon: string, text: string, x, y, w, h: float, color: Color) =
|
||||||
|
|
||||||
var
|
var
|
||||||
bg: Paint
|
bg: Paint
|
||||||
|
|
@ -140,50 +140,50 @@ proc drawButton*(preicon: string, text: string, x, y, w, h: float, color: Color)
|
||||||
tw = 0.0
|
tw = 0.0
|
||||||
iw = 0.0
|
iw = 0.0
|
||||||
|
|
||||||
bg = nanovg.linearGradient(
|
bg = vg.linearGradient(
|
||||||
x,y,x,y+h,
|
x,y,x,y+h,
|
||||||
rgba(255,255,255, if isBlack(color): 16 else:32),
|
rgba(255,255,255, if isBlack(color): 16 else:32),
|
||||||
rgba(0,0,0, if isBlack(color): 16 else:32)
|
rgba(0,0,0, if isBlack(color): 16 else:32)
|
||||||
)
|
)
|
||||||
|
|
||||||
nanovg.beginPath()
|
vg.beginPath()
|
||||||
nanovg.pathRoundedRect(x+1, y+1, w-2, h-2, cornerRadius-1)
|
vg.pathRoundedRect(x+1, y+1, w-2, h-2, cornerRadius-1)
|
||||||
|
|
||||||
if not isBlack(color):
|
if not isBlack(color):
|
||||||
nanovg.setFillColor(color)
|
vg.setFillColor(color)
|
||||||
nanovg.pathFill()
|
vg.pathFill()
|
||||||
|
|
||||||
nanovg.setFillPaint(bg)
|
vg.setFillPaint(bg)
|
||||||
nanovg.pathFill()
|
vg.pathFill()
|
||||||
|
|
||||||
nanovg.beginPath()
|
vg.beginPath()
|
||||||
nanovg.pathRoundedRect(x+0.5, y+0.5, w-1, h-1, cornerRadius-0.5)
|
vg.pathRoundedRect(x+0.5, y+0.5, w-1, h-1, cornerRadius-0.5)
|
||||||
nanovg.setStrokeColor(rgba(0,0,0,48))
|
vg.setStrokeColor(rgba(0,0,0,48))
|
||||||
nanovg.pathStroke()
|
vg.pathStroke()
|
||||||
|
|
||||||
nanovg.setFontSize(20.0)
|
vg.setFontSize(20.0)
|
||||||
nanovg.setFont("sans-bold")
|
vg.setFont("sans-bold")
|
||||||
tb = nanovg.textBounds(text, 0.0, 0.0)
|
tb = vg.textBounds(text, 0.0, 0.0)
|
||||||
tw = tb.horizontalAdvance
|
tw = tb.horizontalAdvance
|
||||||
|
|
||||||
nanovg.setFontSize(h*0.5)
|
vg.setFontSize(h*0.5)
|
||||||
nanovg.setFont("fa")
|
vg.setFont("fa")
|
||||||
ib = nanovg.textBounds(preicon, 0, 0)
|
ib = vg.textBounds(preicon, 0, 0)
|
||||||
iw = ib.horizontalAdvance
|
iw = ib.horizontalAdvance
|
||||||
iw += h*0.15
|
iw += h*0.15
|
||||||
|
|
||||||
nanovg.setFontSize(h*0.5)
|
vg.setFontSize(h*0.5)
|
||||||
nanovg.setFont("fa")
|
vg.setFont("fa")
|
||||||
nanovg.setFillColor(rgba(255,255,255,96))
|
vg.setFillColor(rgba(255,255,255,96))
|
||||||
nanovg.textAlign("left middle")
|
vg.textAlign("left middle")
|
||||||
nanovg.text(preicon, x+w*0.5-tw*0.5-iw*0.75, y+h*0.5)
|
vg.text(preicon, x+w*0.5-tw*0.5-iw*0.75, y+h*0.5)
|
||||||
|
|
||||||
nanovg.setFontSize(20.0)
|
vg.setFontSize(20.0)
|
||||||
nanovg.setFont("sans-bold")
|
vg.setFont("sans-bold")
|
||||||
nanovg.textAlign("left middle")
|
vg.textAlign("left middle")
|
||||||
nanovg.setFillColor(rgba(0,0,0,160))
|
vg.setFillColor(rgba(0,0,0,160))
|
||||||
nanovg.text(text, x+w*0.5-tw*0.5+iw*0.25, y+h*0.5-1)
|
vg.text(text, x+w*0.5-tw*0.5+iw*0.25, y+h*0.5-1)
|
||||||
nanovg.setFillColor(rgba(255,255,255,160))
|
vg.setFillColor(rgba(255,255,255,160))
|
||||||
nanovg.text(text, x+w*0.5-tw*0.5+iw*0.25, y+h*0.5)
|
vg.text(text, x+w*0.5-tw*0.5+iw*0.25, y+h*0.5)
|
||||||
|
|
||||||
proc glewInit*() {.header:"<GL/glew.h>".}
|
proc glewInit*() {.header:"<GL/glew.h>".}
|
||||||
|
|
@ -23,10 +23,10 @@ proc main =
|
||||||
setTime(0)
|
setTime(0)
|
||||||
|
|
||||||
glewInit()
|
glewInit()
|
||||||
nanovg.init()
|
let vg = nanovg.newContext()
|
||||||
nanovg.loadFont(currentSourceDir()/"resources/Roboto-Regular.ttf", "sans")
|
vg.loadFont(currentSourceDir()/"resources/Roboto-Regular.ttf", "sans")
|
||||||
nanovg.loadFont(currentSourceDir()/"resources/Roboto-Bold.ttf", "sans-bold")
|
vg.loadFont(currentSourceDir()/"resources/Roboto-Bold.ttf", "sans-bold")
|
||||||
nanovg.loadFont(currentSourceDir()/"resources/fa.ttf", "fa")
|
vg.loadFont(currentSourceDir()/"resources/fa.ttf", "fa")
|
||||||
var prevt = getTime()
|
var prevt = getTime()
|
||||||
|
|
||||||
while not w.shouldClose():
|
while not w.shouldClose():
|
||||||
|
|
@ -43,16 +43,16 @@ proc main =
|
||||||
glClearColor(0.3, 0.3, 0.32, 1.0)
|
glClearColor(0.3, 0.3, 0.32, 1.0)
|
||||||
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT)
|
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT)
|
||||||
|
|
||||||
withFrame(w):
|
vg.withFrame(w):
|
||||||
let x = glyphPositions("Some仮名thing is up", 0, 0)
|
let x = vg.glyphPositions("Some仮名thing is up", 0, 0)
|
||||||
drawWindow("Title", 50, 50, 300, 400)
|
vg.drawWindow("Title", 50, 50, 300, 400)
|
||||||
drawLabel("Hello!", 10, 10, 280, 20)
|
vg.drawLabel("Hello!", 10, 10, 280, 20)
|
||||||
drawButton(ICON_TRASH, "Delete", 100, 200, 160, 28, rgba(128, 16, 8, 255))
|
vg.drawButton(ICON_TRASH, "Delete", 100, 200, 160, 28, rgba(128, 16, 8, 255))
|
||||||
drawButton(ICON_TRASH, "Deleter", 100, 250, 160, 28, rgba(12, 130, 80, 255))
|
vg.drawButton(ICON_TRASH, "Deleter", 100, 250, 160, 28, rgba(12, 130, 80, 255))
|
||||||
drawButton("Testing", 100, 300, 160, 28)
|
vg.drawButton("Testing", 100, 300, 160, 28)
|
||||||
|
|
||||||
fps.render(5, 5)
|
vg.render(fps, 5, 5)
|
||||||
cpuGraph.render(210, 5)
|
vg.render(cpuGraph, 210, 5)
|
||||||
|
|
||||||
w.swapBuffers()
|
w.swapBuffers()
|
||||||
pollEvents()
|
pollEvents()
|
||||||
|
|
@ -64,6 +64,7 @@ proc main =
|
||||||
waitEvents()
|
waitEvents()
|
||||||
|
|
||||||
w.destroy()
|
w.destroy()
|
||||||
|
vg.delete()
|
||||||
glfw.terminate()
|
glfw.terminate()
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
|
||||||
|
|
@ -71,11 +71,11 @@ proc main() =
|
||||||
var prevt: float = sdl.getTicks().float/1000.0
|
var prevt: float = sdl.getTicks().float/1000.0
|
||||||
|
|
||||||
glewInit()
|
glewInit()
|
||||||
nanovg.init()
|
let vg = nanovg.newContext()
|
||||||
nanovg.loadFont(currentSourceDir()/"resources/Roboto-Regular.ttf", "sans")
|
vg.loadFont(currentSourceDir()/"resources/Roboto-Regular.ttf", "sans")
|
||||||
nanovg.loadFont(currentSourceDir()/"resources/Roboto-Bold.ttf", "sans-bold")
|
vg.loadFont(currentSourceDir()/"resources/Roboto-Bold.ttf", "sans-bold")
|
||||||
nanovg.loadFont(currentSourceDir()/"resources/fa.ttf", "fa")
|
vg.loadFont(currentSourceDir()/"resources/fa.ttf", "fa")
|
||||||
nanovg.loadFont(currentSourceDir()/"resources/entypo.ttf", "icons")
|
vg.loadFont(currentSourceDir()/"resources/entypo.ttf", "icons")
|
||||||
|
|
||||||
while not done:
|
while not done:
|
||||||
let fbSize = window.frameBufferSize()
|
let fbSize = window.frameBufferSize()
|
||||||
|
|
@ -86,16 +86,16 @@ proc main() =
|
||||||
glClearColor(0.3, 0.3, 0.32, 1.0)
|
glClearColor(0.3, 0.3, 0.32, 1.0)
|
||||||
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT)
|
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT)
|
||||||
|
|
||||||
withFrame(window):
|
vg.withFrame(window):
|
||||||
let x = glyphPositions("Some仮名thing is up", 0, 0)
|
let x = glyphPositions(vg, "Some仮名thing is up", 0, 0)
|
||||||
drawWindow("Title", 50, 50, 300, 400)
|
vg.drawWindow("Title", 50, 50, 300, 400)
|
||||||
drawLabel("Hello!", 10, 10, 280, 20)
|
vg.drawLabel("Hello!", 10, 10, 280, 20)
|
||||||
drawButton(ICON_TRASH, "Delete", 100, 200, 160, 28, rgba(128, 16, 8, 255))
|
vg.drawButton(ICON_TRASH, "Delete", 100, 200, 160, 28, rgba(128, 16, 8, 255))
|
||||||
drawButton(ICON_TRASH, "Deleter", 100, 250, 160, 28, rgba(12, 130, 80, 255))
|
vg.drawButton(ICON_TRASH, "Deleter", 100, 250, 160, 28, rgba(12, 130, 80, 255))
|
||||||
drawButton("Testing", 100, 300, 160, 28)
|
vg.drawButton("Testing", 100, 300, 160, 28)
|
||||||
|
|
||||||
fps.render(5, 5)
|
vg.render(fps, 5, 5)
|
||||||
cpuGraph.render(210, 5)
|
vg.render(cpuGraph, 210, 5)
|
||||||
|
|
||||||
let t: float = sdl.getTicks().float/1000.0
|
let t: float = sdl.getTicks().float/1000.0
|
||||||
let dt = t - prevt
|
let dt = t - prevt
|
||||||
|
|
@ -112,6 +112,7 @@ proc main() =
|
||||||
|
|
||||||
sdl.glDeleteContext(context)
|
sdl.glDeleteContext(context)
|
||||||
window.destroyWindow()
|
window.destroyWindow()
|
||||||
|
vg.delete()
|
||||||
img.quit()
|
img.quit()
|
||||||
sdl.quit()
|
sdl.quit()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,12 +91,12 @@ proc main() =
|
||||||
gpu.setRequiredFeatures(gpu.FEATURE_BASIC_SHADERS)
|
gpu.setRequiredFeatures(gpu.FEATURE_BASIC_SHADERS)
|
||||||
|
|
||||||
|
|
||||||
nanovg.init()
|
let vg = nanovg.newContext()
|
||||||
discard sdl.glSetSwapInterval(0)
|
discard sdl.glSetSwapInterval(0)
|
||||||
nanovg.loadFont(currentSourceDir()/"resources/Roboto-Regular.ttf", "sans")
|
vg.loadFont(currentSourceDir()/"resources/umeboshi.ttf", "sans")
|
||||||
nanovg.loadFont(currentSourceDir()/"resources/Roboto-Bold.ttf", "sans-bold")
|
vg.loadFont(currentSourceDir()/"resources/Roboto-Bold.ttf", "sans-bold")
|
||||||
nanovg.loadFont(currentSourceDir()/"resources/fa.ttf", "fa")
|
vg.loadFont(currentSourceDir()/"resources/fa.ttf", "fa")
|
||||||
nanovg.loadFont(currentSourceDir()/"resources/entypo.ttf", "icons")
|
vg.loadFont(currentSourceDir()/"resources/entypo.ttf", "icons")
|
||||||
|
|
||||||
var done = false
|
var done = false
|
||||||
var prevt: float = sdl.getTicks().float/1000.0
|
var prevt: float = sdl.getTicks().float/1000.0
|
||||||
|
|
@ -122,18 +122,18 @@ proc main() =
|
||||||
|
|
||||||
gpu.flushBlitBuffer()
|
gpu.flushBlitBuffer()
|
||||||
|
|
||||||
withFrame(window):
|
withFrame(vg, window):
|
||||||
text("Some仮名thing is up", 100, 100, 100)
|
vg.text("Some仮名thing is up", 100, 100, 100)
|
||||||
drawWindow("Title", 50, 50, 300, 400)
|
vg.drawWindow("Title", 50, 50, 300, 400)
|
||||||
drawLabel("Hello!", 10, 10, 500, 20)
|
vg.drawLabel("Hello!", 10, 10, 500, 20)
|
||||||
drawButton(ICON_TRASH, "Delete", 100, 200, 160, 28, rgba(128, 16, 8, 255))
|
vg.drawButton(ICON_TRASH, "Delete", 100, 200, 160, 28, rgba(128, 16, 8, 255))
|
||||||
drawButton(ICON_TRASH, "Deleter", 100, 250, 160, 28, rgba(12, 130, 80, 255))
|
vg.drawButton(ICON_TRASH, "Deleter", 100, 250, 160, 28, rgba(12, 130, 80, 255))
|
||||||
drawButton("Testing", 100, 300, 160, 28)
|
vg.drawButton("Testing", 100, 300, 160, 28)
|
||||||
|
|
||||||
gpu.resetRendererState()
|
gpu.resetRendererState()
|
||||||
|
|
||||||
fps.render(5, 5)
|
vg.render(fps, 5, 5)
|
||||||
cpuGraph.render(210, 5)
|
vg.render(cpuGraph, 210, 5)
|
||||||
|
|
||||||
|
|
||||||
gpu.flip(screen)
|
gpu.flip(screen)
|
||||||
|
|
@ -149,6 +149,7 @@ proc main() =
|
||||||
|
|
||||||
done = events()
|
done = events()
|
||||||
gpu.freeImage(image)
|
gpu.freeImage(image)
|
||||||
|
vg.delete()
|
||||||
gpu.quit()
|
gpu.quit()
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
@ -32,19 +32,19 @@ proc getGraphAverage(graph: PerfGraph): float =
|
||||||
|
|
||||||
return avg / GRAPH_HISTORY_COUNT.float
|
return avg / GRAPH_HISTORY_COUNT.float
|
||||||
|
|
||||||
proc render*(graph: PerfGraph, x, y: float) =
|
proc render*(vg: Context, graph: PerfGraph, x, y: float) =
|
||||||
let
|
let
|
||||||
avg = getGraphAverage(graph)
|
avg = getGraphAverage(graph)
|
||||||
width: float = 200
|
width: float = 200
|
||||||
height: float = 35
|
height: float = 35
|
||||||
|
|
||||||
nanovg.beginPath()
|
vg.beginPath()
|
||||||
nanovg.pathRect(x, y, width, height)
|
vg.pathRect(x, y, width, height)
|
||||||
nanovg.setFillColor(0, 0, 0, 128)
|
vg.setFillColor(0, 0, 0, 128)
|
||||||
nanovg.pathFill()
|
vg.pathFill()
|
||||||
|
|
||||||
nanovg.beginPath()
|
vg.beginPath()
|
||||||
nanovg.pathMoveTo(x, y+height)
|
vg.pathMoveTo(x, y+height)
|
||||||
|
|
||||||
case graph.style:
|
case graph.style:
|
||||||
of RenderStyle.FPS:
|
of RenderStyle.FPS:
|
||||||
|
|
@ -58,7 +58,7 @@ proc render*(graph: PerfGraph, x, y: float) =
|
||||||
vx = x + (i/(GRAPH_HISTORY_COUNT-1)) * width
|
vx = x + (i/(GRAPH_HISTORY_COUNT-1)) * width
|
||||||
vy = y + height - ((v / 80) * height)
|
vy = y + height - ((v / 80) * height)
|
||||||
|
|
||||||
nanovg.pathLineTo(vx, vy)
|
vg.pathLineTo(vx, vy)
|
||||||
|
|
||||||
of RenderStyle.PERCENT:
|
of RenderStyle.PERCENT:
|
||||||
for i in 0 ..< GRAPH_HISTORY_COUNT:
|
for i in 0 ..< GRAPH_HISTORY_COUNT:
|
||||||
|
|
@ -71,7 +71,7 @@ proc render*(graph: PerfGraph, x, y: float) =
|
||||||
vx = x + (i/(GRAPH_HISTORY_COUNT-1)) * width
|
vx = x + (i/(GRAPH_HISTORY_COUNT-1)) * width
|
||||||
vy = y + height - ((v / 100) * height)
|
vy = y + height - ((v / 100) * height)
|
||||||
|
|
||||||
nanovg.pathLineTo(vx, vy)
|
vg.pathLineTo(vx, vy)
|
||||||
|
|
||||||
of RenderStyle.MS:
|
of RenderStyle.MS:
|
||||||
for i in 0 ..< GRAPH_HISTORY_COUNT:
|
for i in 0 ..< GRAPH_HISTORY_COUNT:
|
||||||
|
|
@ -84,40 +84,40 @@ proc render*(graph: PerfGraph, x, y: float) =
|
||||||
vx = x + (i/(GRAPH_HISTORY_COUNT-1)) * width
|
vx = x + (i/(GRAPH_HISTORY_COUNT-1)) * width
|
||||||
vy = y + height - ((v / 20) * height)
|
vy = y + height - ((v / 20) * height)
|
||||||
|
|
||||||
nanovg.pathLineTo(vx, vy)
|
vg.pathLineTo(vx, vy)
|
||||||
|
|
||||||
nanovg.pathLineTo(x+width, y+height)
|
vg.pathLineTo(x+width, y+height)
|
||||||
nanovg.setFillColor(255, 192, 0, 128)
|
vg.setFillColor(255, 192, 0, 128)
|
||||||
nanovg.pathFill()
|
vg.pathFill()
|
||||||
|
|
||||||
nanovg.setFont("sans")
|
vg.setFont("sans")
|
||||||
|
|
||||||
if graph.name.len() > 0:
|
if graph.name.len() > 0:
|
||||||
nanovg.setFontSize(14)
|
vg.setFontSize(14)
|
||||||
nanovg.textAlign("top left")
|
vg.textAlign("top left")
|
||||||
nanovg.setFillColor(240, 240, 240, 192)
|
vg.setFillColor(240, 240, 240, 192)
|
||||||
nanovg.text(graph.name, x+3, y+1)
|
vg.text(graph.name, x+3, y+1)
|
||||||
|
|
||||||
nanovg.setFontSize(18)
|
vg.setFontSize(18)
|
||||||
nanovg.textAlign("top right")
|
vg.textAlign("top right")
|
||||||
nanovg.setFillColor(240, 240, 240, 255)
|
vg.setFillColor(240, 240, 240, 255)
|
||||||
|
|
||||||
case graph.style:
|
case graph.style:
|
||||||
of RenderStyle.FPS:
|
of RenderStyle.FPS:
|
||||||
var str = fmt"{1.0/avg:.2f} FPS"
|
var str = fmt"{1.0/avg:.2f} FPS"
|
||||||
|
|
||||||
nanovg.text(str, x+width-3, y+1)
|
vg.text(str, x+width-3, y+1)
|
||||||
nanovg.setFontSize(15)
|
vg.setFontSize(15)
|
||||||
nanovg.textAlign("bottom right")
|
vg.textAlign("bottom right")
|
||||||
nanovg.setFillColor(240, 240, 240, 160)
|
vg.setFillColor(240, 240, 240, 160)
|
||||||
|
|
||||||
str = fmt"{avg*1000:.2f} ms"
|
str = fmt"{avg*1000:.2f} ms"
|
||||||
nanovg.text(str, x+width-3, y+height-1)
|
vg.text(str, x+width-3, y+height-1)
|
||||||
|
|
||||||
of RenderStyle.PERCENT:
|
of RenderStyle.PERCENT:
|
||||||
let str = fmt"{avg:.1f} %"
|
let str = fmt"{avg:.1f} %"
|
||||||
nanovg.text(str, x+width-3, y+1)
|
vg.text(str, x+width-3, y+1)
|
||||||
|
|
||||||
of RenderStyle.MS:
|
of RenderStyle.MS:
|
||||||
let str = fmt"{avg*1000:.2f} ms"
|
let str = fmt"{avg*1000:.2f} ms"
|
||||||
nanovg.text(str, x+width-3, y+1)
|
vg.text(str, x+width-3, y+1)
|
||||||
|
|
|
||||||
295
src/nanovg.nim
295
src/nanovg.nim
|
|
@ -24,7 +24,7 @@ type
|
||||||
FontLoadError* = object of CatchableError
|
FontLoadError* = object of CatchableError
|
||||||
ImageLoadError* = object of CatchableError
|
ImageLoadError* = object of CatchableError
|
||||||
ContextInitError* = object of CatchableError
|
ContextInitError* = object of CatchableError
|
||||||
Context = ptr NVGContext
|
Context* = ptr NVGContext
|
||||||
|
|
||||||
Alignment* {.size: sizeof(cint), pure.} = enum
|
Alignment* {.size: sizeof(cint), pure.} = enum
|
||||||
NONE = 0
|
NONE = 0
|
||||||
|
|
@ -114,7 +114,7 @@ type
|
||||||
proc width*(pos: GlyphPosition): float =
|
proc width*(pos: GlyphPosition): float =
|
||||||
return pos.maxX - pos.minX
|
return pos.maxX - pos.minX
|
||||||
|
|
||||||
proc createExpr*(ty, name: string, descriptor: NimNode, args: varargs[NimNode]): NimNode =
|
proc createExpr*(context: NimNode, ty, name: string, descriptor: NimNode, args: varargs[NimNode]): NimNode =
|
||||||
let tokens = ($descriptor).toUpper().split(" ").map(
|
let tokens = ($descriptor).toUpper().split(" ").map(
|
||||||
proc(s: string): string =
|
proc(s: string): string =
|
||||||
return ty & "." & s
|
return ty & "." & s
|
||||||
|
|
@ -127,7 +127,7 @@ proc createExpr*(ty, name: string, descriptor: NimNode, args: varargs[NimNode]):
|
||||||
|
|
||||||
let allTokens = argTokens.concat(tokens)
|
let allTokens = argTokens.concat(tokens)
|
||||||
|
|
||||||
let newExpr = name & "(" & allTokens.join(",") & ")"
|
let newExpr = name & "(" & $context.toStrLit & ", " & allTokens.join(",") & ")"
|
||||||
|
|
||||||
result = parseStmt(newExpr)
|
result = parseStmt(newExpr)
|
||||||
|
|
||||||
|
|
@ -140,7 +140,10 @@ template reduce[T](elements: openArray[T], op: untyped): untyped =
|
||||||
|
|
||||||
res
|
res
|
||||||
|
|
||||||
proc createContext(antialias = true, stencilStrokes = true, debugChecks = false): Context =
|
proc delete*(context: Context) =
|
||||||
|
context.deleteGL3()
|
||||||
|
|
||||||
|
proc newContext*(antialias = true, stencilStrokes = true, debugChecks = false): Context =
|
||||||
var flags: cint
|
var flags: cint
|
||||||
|
|
||||||
if antialias:
|
if antialias:
|
||||||
|
|
@ -155,83 +158,78 @@ proc createContext(antialias = true, stencilStrokes = true, debugChecks = false)
|
||||||
if result.isNil:
|
if result.isNil:
|
||||||
raise newException(ContextInitError, "Could not initialize graphics context")
|
raise newException(ContextInitError, "Could not initialize graphics context")
|
||||||
|
|
||||||
var context: Context
|
proc loadFont*(context: Context, path, name: string): Font {.discardable.} =
|
||||||
|
|
||||||
proc init*() =
|
|
||||||
context = createContext()
|
|
||||||
|
|
||||||
proc loadFont*(path, name: string): Font {.discardable.} =
|
|
||||||
## Load the font from `path` and give it a `name` that can be used to reference it.
|
## Load the font from `path` and give it a `name` that can be used to reference it.
|
||||||
result = context.createFont(name, path)
|
result = context.createFont(name, path)
|
||||||
|
|
||||||
if result == -1:
|
if result == -1:
|
||||||
raise newException(FontLoadError, fmt"Could not load font {name}.")
|
raise newException(FontLoadError, fmt"Could not load font {name}.")
|
||||||
|
|
||||||
proc loadFontMem*(data: openArray[uint8], name: string, freeDataAutomatically = true): Font {.discardable.} =
|
proc loadFontMem*(context: Context, data: openArray[uint8], name: string, freeDataAutomatically = true): Font {.discardable.} =
|
||||||
## Load the font from `path` and give it a `name` that can be used to reference it.
|
## Load the font from `path` and give it a `name` that can be used to reference it.
|
||||||
result = context.createFontMem(name, cast[ptr cuchar](data[0].unsafeAddr), data.len.cint, freeDataAutomatically.cint)
|
result = context.createFontMem(name, cast[ptr cuchar](data[0].unsafeAddr), data.len.cint, freeDataAutomatically.cint)
|
||||||
|
|
||||||
if result == -1:
|
if result == -1:
|
||||||
raise newException(FontLoadError, fmt"Could not load font {name}.")
|
raise newException(FontLoadError, fmt"Could not load font {name}.")
|
||||||
|
|
||||||
proc findFont*(name: string): Font =
|
proc findFont*(context: Context, name: string): Font =
|
||||||
return context.findFont(name)
|
return context.findFont(name)
|
||||||
|
|
||||||
proc setFallbackFont*(baseFont, fallbackFont: string): Font =
|
proc setFallbackFont*(context: Context, baseFont, fallbackFont: string): Font =
|
||||||
return context.addFallbackFont(baseFont, fallbackFont)
|
return context.addFallbackFont(baseFont, fallbackFont)
|
||||||
|
|
||||||
proc setFallbackFont*(baseFont, fallbackFont: Font): Font =
|
proc setFallbackFont*(context: Context, baseFont, fallbackFont: Font): Font =
|
||||||
return context.addFallbackFontId(baseFont, fallbackFont)
|
return context.addFallbackFontId(baseFont, fallbackFont)
|
||||||
|
|
||||||
proc setFont*(font: Font) =
|
proc `font=`*(context: Context, font: Font) =
|
||||||
context.fontFaceId(font)
|
context.fontFaceId(font)
|
||||||
|
|
||||||
proc setFont*(name: string) =
|
proc setFont*(context: Context, name: string) =
|
||||||
context.fontFace(name)
|
context.fontFace(name)
|
||||||
|
|
||||||
proc setFontSize*(size: float) =
|
proc setFontSize*(context: Context, size: float) =
|
||||||
context.fontSize(size)
|
context.fontSize(size)
|
||||||
|
|
||||||
proc setFontBlur*(blur: float) =
|
proc setFontBlur*(context: Context, blur: float) =
|
||||||
context.fontBlur(blur)
|
context.fontBlur(blur)
|
||||||
|
|
||||||
proc setTextLetterSpacing*(spacing: float) =
|
proc setTextLetterSpacing*(context: Context, spacing: float) =
|
||||||
context.textLetterSpacing(spacing)
|
context.textLetterSpacing(spacing)
|
||||||
|
|
||||||
proc setTextLineHeight*(lineHeight: float) =
|
proc setTextLineHeight*(context: Context, lineHeight: float) =
|
||||||
context.textLineHeight(lineHeight)
|
context.textLineHeight(lineHeight)
|
||||||
|
|
||||||
proc `or`(align1: Alignment, align2: Alignment): Alignment =
|
proc `or`(align1: Alignment, align2: Alignment): Alignment =
|
||||||
return (align1.cint or align2.cint).Alignment
|
return (align1.cint or align2.cint).Alignment
|
||||||
|
|
||||||
proc textAlign*(alignments: varargs[Alignment]) =
|
proc textAlign*(context: Context, alignments: varargs[Alignment]) =
|
||||||
var alignment = reduce(alignments, `or`)
|
var alignment = reduce(alignments, `or`)
|
||||||
|
|
||||||
context.textAlign(alignment.cint)
|
context.textAlign(alignment.cint)
|
||||||
|
|
||||||
macro textAlign*(descriptor: string) =
|
macro textAlign*(context: Context, descriptor: string) =
|
||||||
result = createExpr("Alignment", "textAlign", descriptor)
|
result = createExpr(context, "Alignment", "textAlign", descriptor)
|
||||||
|
|
||||||
proc textBounds*(text: string, x, y: float): TextBounds =
|
proc textBounds*(context: Context, text: string, x, y: float): TextBounds =
|
||||||
var res: array[4, cfloat]
|
var res: array[4, cfloat]
|
||||||
let horizonalAdvance = context.textBounds(x, y, text, nil, res[0].addr)
|
let horizonalAdvance = context.textBounds(x, y, text, nil, res[0].addr)
|
||||||
|
|
||||||
let bounds: Bounds = (res[0].float, res[1].float, res[2].float, res[3].float)
|
let bounds: Bounds = (res[0].float, res[1].float, res[2].float, res[3].float)
|
||||||
return (horizonalAdvance.float, bounds)
|
return (horizonalAdvance.float, bounds)
|
||||||
|
|
||||||
proc text*(text: string, x, y: float) =
|
proc text*(context: Context, text: string, x, y: float) =
|
||||||
discard context.text(x, y, text, nil)
|
discard context.text(x, y, text, nil)
|
||||||
|
|
||||||
proc textBoxBounds*(text: string, x, y, breakRowWidth: float): Bounds =
|
proc textBoxBounds*(context: Context, text: string, x, y, breakRowWidth: float): Bounds =
|
||||||
var res: array[4, cfloat]
|
var res: array[4, cfloat]
|
||||||
context.textBoxBounds(x, y, breakRowWidth, text, nil, res[0].addr)
|
context.textBoxBounds(x, y, breakRowWidth, text, nil, res[0].addr)
|
||||||
|
|
||||||
return (res[0].float, res[1].float, res[2].float, res[3].float)
|
return (res[0].float, res[1].float, res[2].float, res[3].float)
|
||||||
|
|
||||||
proc textBox*(text: string, x, y, breakRowWidth: float) =
|
proc textBox*(context: Context, text: string, x, y, breakRowWidth: float) =
|
||||||
context.textBox(x, y, breakRowWidth, text, nil)
|
context.textBox(x, y, breakRowWidth, text, nil)
|
||||||
|
|
||||||
proc textMetrics*(): TextMetrics =
|
proc textMetrics*(context: Context): TextMetrics =
|
||||||
var
|
var
|
||||||
ascender, descender, lineHeight: cfloat
|
ascender, descender, lineHeight: cfloat
|
||||||
|
|
||||||
|
|
@ -239,7 +237,7 @@ proc textMetrics*(): TextMetrics =
|
||||||
|
|
||||||
return (ascender.float, descender.float, lineHeight.float)
|
return (ascender.float, descender.float, lineHeight.float)
|
||||||
|
|
||||||
iterator glyphPositions(start: cstring, endPos: cstring, x, y: float): GlyphPosition =
|
iterator glyphPositions(context: Context, start: cstring, endPos: cstring, x, y: float): GlyphPosition =
|
||||||
const maxPositions = 100
|
const maxPositions = 100
|
||||||
var
|
var
|
||||||
positions: array[maxPositions, NVGglyphPosition]
|
positions: array[maxPositions, NVGglyphPosition]
|
||||||
|
|
@ -247,7 +245,7 @@ iterator glyphPositions(start: cstring, endPos: cstring, x, y: float): GlyphPosi
|
||||||
bytesProcessed = 0
|
bytesProcessed = 0
|
||||||
lastX = x
|
lastX = x
|
||||||
strIndex = 0
|
strIndex = 0
|
||||||
lineHeight = textMetrics().lineHeight
|
lineHeight = context.textMetrics().lineHeight
|
||||||
|
|
||||||
let strLen = cast[ByteAddress](endPos) - cast[ByteAddress](start)
|
let strLen = cast[ByteAddress](endPos) - cast[ByteAddress](start)
|
||||||
|
|
||||||
|
|
@ -285,17 +283,17 @@ iterator glyphPositions(start: cstring, endPos: cstring, x, y: float): GlyphPosi
|
||||||
lastX = positions[numGlyphs-1].x
|
lastX = positions[numGlyphs-1].x
|
||||||
strIndex += maxPositions
|
strIndex += maxPositions
|
||||||
|
|
||||||
proc glyphPositions*(text: string, x, y: float): seq[GlyphPosition] =
|
proc glyphPositions*(context: Context, text: string, x, y: float): seq[GlyphPosition] =
|
||||||
result = newSeqOfCap[GlyphPosition](100)
|
result = newSeqOfCap[GlyphPosition](100)
|
||||||
for gpos in glyphPositions(cast[cstring](text[0].unsafeAddr), nil, x, y):
|
for gpos in context.glyphPositions(cast[cstring](text[0].unsafeAddr), nil, x, y):
|
||||||
result.add gpos
|
result.add gpos
|
||||||
|
|
||||||
proc glyphPositions*(row: NVGtextRow, x, y: float): seq[GlyphPosition] =
|
proc glyphPositions*(context: Context, row: NVGtextRow, x, y: float): seq[GlyphPosition] =
|
||||||
result = newSeqOfCap[GlyphPosition](100)
|
result = newSeqOfCap[GlyphPosition](100)
|
||||||
for gpos in glyphPositions(row.start, row.`end`, x, y):
|
for gpos in context.glyphPositions(row.start, row.`end`, x, y):
|
||||||
result.add gpos
|
result.add gpos
|
||||||
|
|
||||||
iterator textRows(text: string, x, y, maxWidth: float): NVGtextRow =
|
iterator textRows(context: Context, text: string, x, y, maxWidth: float): NVGtextRow =
|
||||||
const maxRows = 10
|
const maxRows = 10
|
||||||
var
|
var
|
||||||
rows: array[maxRows, NVGtextRow]
|
rows: array[maxRows, NVGtextRow]
|
||||||
|
|
@ -315,48 +313,43 @@ iterator textRows(text: string, x, y, maxWidth: float): NVGtextRow =
|
||||||
|
|
||||||
start = rows[numRows-1].next
|
start = rows[numRows-1].next
|
||||||
|
|
||||||
proc glyphPositions*(text: string, x, y, maxWidth: float): seq[GlyphPosition] =
|
proc glyphPositions*(context: Context, text: string, x, y, maxWidth: float): seq[GlyphPosition] =
|
||||||
var newY = y
|
var newY = y
|
||||||
|
|
||||||
for row in textRows(text, x, y, maxWidth):
|
for row in context.textRows(text, x, y, maxWidth):
|
||||||
let glyphPositions = row.glyphPositions(x, newY)
|
let glyphPositions = context.glyphPositions(row, x, newY)
|
||||||
result.add(glyphPositions)
|
result.add(glyphPositions)
|
||||||
newY += glyphPositions[0].height
|
newY += glyphPositions[0].height
|
||||||
|
|
||||||
proc text*(text: string, x, y, maxWidth: float) =
|
proc text*(context: Context, text: string, x, y, maxWidth: float) =
|
||||||
var newY = y
|
var newY = y
|
||||||
|
|
||||||
for row in textRows(text, x, y, maxWidth):
|
for row in context.textRows(text, x, y, maxWidth):
|
||||||
discard context.text(x, newY, row.start, row.`end`)
|
discard context.text(x, newY, row.start, row.`end`)
|
||||||
newY += textMetrics().lineHeight
|
newY += context.textMetrics().lineHeight
|
||||||
|
|
||||||
proc beginFrame*(width, height, pxRatio: float) =
|
export beginFrame
|
||||||
context.beginFrame(width, height, pxRatio)
|
export endFrame
|
||||||
|
export cancelFrame
|
||||||
|
|
||||||
proc cancelFrame*() =
|
proc globalCompositeOperation*(context: Context, op: CompositeOperation) =
|
||||||
context.cancelFrame()
|
|
||||||
|
|
||||||
proc endFrame*() =
|
|
||||||
context.endFrame()
|
|
||||||
|
|
||||||
proc globalCompositeOperation*(op: CompositeOperation) =
|
|
||||||
context.globalCompositeOperation(op.cint)
|
context.globalCompositeOperation(op.cint)
|
||||||
|
|
||||||
proc globalCompositeBlendFunc*(sourceFactor, destFactor: BlendFactor) =
|
proc globalCompositeBlendFunc*(context: Context, sourceFactor, destFactor: BlendFactor) =
|
||||||
context.globalCompositeBlendFunc(sourceFactor.cint, destFactor.cint)
|
context.globalCompositeBlendFunc(sourceFactor.cint, destFactor.cint)
|
||||||
|
|
||||||
proc globalCompositeBlendFuncSeparate*(srcRGB, destRGB, srcAlpha, destAlpha: BlendFactor) =
|
proc globalCompositeBlendFuncSeparate*(context: Context, srcRGB, destRGB, srcAlpha, destAlpha: BlendFactor) =
|
||||||
context.globalCompositeBlendFuncSeparate(srcRGB.cint, destRGB.cint, srcAlpha.cint, destAlpha.cint)
|
context.globalCompositeBlendFuncSeparate(srcRGB.cint, destRGB.cint, srcAlpha.cint, destAlpha.cint)
|
||||||
|
|
||||||
template withFrame*(window: View, code: untyped) =
|
template withFrame*(context: Context, window: View, code: untyped) =
|
||||||
let
|
let
|
||||||
winSize = window.size()
|
winSize = window.size()
|
||||||
fbSize = window.frameBufferSize()
|
fbSize = window.frameBufferSize()
|
||||||
pxRatio = cfloat(fbSize.w) / cfloat(winSize.w)
|
pxRatio = cfloat(fbSize.w) / cfloat(winSize.w)
|
||||||
|
|
||||||
beginFrame(winSize.w.cfloat, winSize.h.cfloat, pxRatio)
|
context.beginFrame(winSize.w.cfloat, winSize.h.cfloat, pxRatio)
|
||||||
code
|
code
|
||||||
endFrame()
|
context.endFrame()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
@ -366,98 +359,140 @@ template withFrame*(window: View, code: untyped) =
|
||||||
# The state contains transform, fill and stroke styles, text and font styles,
|
# The state contains transform, fill and stroke styles, text and font styles,
|
||||||
# and scissor clipping.
|
# and scissor clipping.
|
||||||
#
|
#
|
||||||
proc saveState*() =
|
proc saveState*(context: Context, ) =
|
||||||
## Pushes and saves the current render state into a state stack.
|
## Pushes and saves the current render state into a state stack.
|
||||||
## A matching restoreState() must be used to restore the state.
|
## A matching restoreState() must be used to restore the state.
|
||||||
context.save()
|
context.save()
|
||||||
|
|
||||||
proc restoreState*() =
|
proc restoreState*(context: Context, ) =
|
||||||
## Pops and restores current render state.
|
## Pops and restores current render state.
|
||||||
context.restore()
|
context.restore()
|
||||||
|
|
||||||
proc resetState*() =
|
proc resetState*(context: Context, ) =
|
||||||
## Resets current render state to default values. Does not affect the render state stack.
|
## Resets current render state to default values. Does not affect the render state stack.
|
||||||
context.reset()
|
context.reset()
|
||||||
|
|
||||||
template withState*(code: untyped) =
|
template withState*(context: Context, code: untyped) =
|
||||||
saveState()
|
context.saveState()
|
||||||
try:
|
try:
|
||||||
code
|
code
|
||||||
except:
|
except:
|
||||||
raise
|
raise
|
||||||
finally:
|
finally:
|
||||||
restoreState()
|
context.restoreState()
|
||||||
|
|
||||||
proc setShapeAntialias*(enabled = true) =
|
proc setShapeAntialias*(context: Context, enabled = true) =
|
||||||
context.shapeAntiAlias(enabled.cint)
|
context.shapeAntiAlias(enabled.cint)
|
||||||
|
|
||||||
proc setStrokeColor*(color: Color) =
|
proc setStrokeColor*(context: Context, color: Color) =
|
||||||
context.strokeColor(color)
|
context.strokeColor(color)
|
||||||
|
|
||||||
proc setStrokePaint*(paint: Paint) =
|
proc setStrokePaint*(context: Context, paint: Paint) =
|
||||||
context.strokePaint(paint)
|
context.strokePaint(paint)
|
||||||
|
|
||||||
proc setFillPaint*(paint: Paint) =
|
proc setFillPaint*(context: Context, paint: Paint) =
|
||||||
context.fillPaint(paint)
|
context.fillPaint(paint)
|
||||||
|
|
||||||
proc setFillColor*(color: Color) =
|
proc setFillColor*(context: Context, color: Color) =
|
||||||
context.fillColor(color)
|
context.fillColor(color)
|
||||||
|
|
||||||
proc setFillColor*(r, g, b: uint8) =
|
proc setFillColor*(context: Context, r, g, b: uint8) =
|
||||||
context.fillColor(rgb(r.cuchar, g.cuchar, b.cuchar))
|
context.fillColor(rgb(r.cuchar, g.cuchar, b.cuchar))
|
||||||
|
|
||||||
proc setFillColor*(r, g, b: float) =
|
proc setFillColor*(context: Context, r, g, b: float) =
|
||||||
context.fillColor(rgbf(r, g, b))
|
context.fillColor(rgbf(r, g, b))
|
||||||
|
|
||||||
proc setFillColor*(r, g, b, a: float) =
|
proc setFillColor*(context: Context, r, g, b, a: float) =
|
||||||
context.fillColor(rgbaf(r, g, b, a))
|
context.fillColor(rgbaf(r, g, b, a))
|
||||||
|
|
||||||
proc setFillColor*(r, g, b, a: uint8) =
|
proc setFillColor*(context: Context, r, g, b, a: uint8) =
|
||||||
context.fillColor(rgba(r.cuchar, g.cuchar, b.cuchar, a.cuchar))
|
context.fillColor(rgba(r.cuchar, g.cuchar, b.cuchar, a.cuchar))
|
||||||
|
|
||||||
proc setMiterLimit*(limit: float) =
|
proc setMiterLimit*(context: Context, limit: float) =
|
||||||
context.miterLimit(limit)
|
context.miterLimit(limit)
|
||||||
|
|
||||||
proc setStrokeWidth*(size: float) =
|
proc setStrokeWidth*(context: Context, size: float) =
|
||||||
context.strokeWidth(size)
|
context.strokeWidth(size)
|
||||||
|
|
||||||
proc setLineCap*(cap: LineCap) =
|
proc setLineCap*(context: Context, cap: LineCap) =
|
||||||
context.lineCap(cap.cint)
|
context.lineCap(cap.cint)
|
||||||
|
|
||||||
proc setLineJoin*(join: LineJoin) =
|
proc setLineJoin*(context: Context, join: LineJoin) =
|
||||||
context.lineJoin(join.cint)
|
context.lineJoin(join.cint)
|
||||||
|
|
||||||
proc setGlobalAlpha*(alpha: float) =
|
proc setGlobalAlpha*(context: Context, alpha: float) =
|
||||||
|
context.globalAlpha(alpha)
|
||||||
|
|
||||||
|
proc `shapeAntialias=`*(context: Context, enabled: bool) =
|
||||||
|
context.shapeAntiAlias(enabled.cint)
|
||||||
|
|
||||||
|
proc `strokeColor`*(context: Context, color: Color) =
|
||||||
|
context.strokeColor(color)
|
||||||
|
|
||||||
|
proc `strokePaint=`*(context: Context, paint: Paint) =
|
||||||
|
context.strokePaint(paint)
|
||||||
|
|
||||||
|
proc `fillPaint=`*(context: Context, paint: Paint) =
|
||||||
|
context.fillPaint(paint)
|
||||||
|
|
||||||
|
proc `fillColor=`*(context: Context, color: Color) =
|
||||||
|
context.fillColor(color)
|
||||||
|
|
||||||
|
proc `fillColor=`*(context: Context, color: tuple[r, g, b: uint8]) =
|
||||||
|
context.fillColor(rgb(color.r.cuchar, color.g.cuchar, color.b.cuchar))
|
||||||
|
|
||||||
|
proc `fillColor=`*(context: Context, color: tuple[r, g, b: float]) =
|
||||||
|
context.fillColor(rgbf(color.r, color.g, color.b))
|
||||||
|
|
||||||
|
proc `fillColor=`*(context: Context, color: tuple[r, g, b, a: float]) =
|
||||||
|
context.fillColor(rgbaf(color.r, color.g, color.b, color.a))
|
||||||
|
|
||||||
|
proc setFillColor*(context: Context, color: tuple[r, g, b, a: uint8]) =
|
||||||
|
context.fillColor(rgba(color.r.cuchar, color.g.cuchar, color.b.cuchar, color.a.cuchar))
|
||||||
|
|
||||||
|
proc `miterLimit=`*(context: Context, limit: float) =
|
||||||
|
context.miterLimit(limit)
|
||||||
|
|
||||||
|
proc `strokeWidth=`*(context: Context, size: float) =
|
||||||
|
context.strokeWidth(size)
|
||||||
|
|
||||||
|
proc `lineCap=`*(context: Context, cap: LineCap) =
|
||||||
|
context.lineCap(cap.cint)
|
||||||
|
|
||||||
|
proc `lineJoin=`*(context: Context, join: LineJoin) =
|
||||||
|
context.lineJoin(join.cint)
|
||||||
|
|
||||||
|
proc `globalAlpha=`*(context: Context, alpha: float) =
|
||||||
context.globalAlpha(alpha)
|
context.globalAlpha(alpha)
|
||||||
|
|
||||||
# Transforms
|
# Transforms
|
||||||
|
|
||||||
proc resetTransform*() =
|
proc resetTransform*(context: Context) {.inline.} =
|
||||||
context.resetTransform()
|
wrapper.resetTransform(context)
|
||||||
|
|
||||||
proc transform*(a, b, c, d, e, f: float) =
|
proc transform*(context: Context, a, b, c, d, e, f: float) =
|
||||||
context.transform(a, b, c, d, e, f)
|
wrapper.transform(context, a, b, c, d, e, f)
|
||||||
|
|
||||||
proc translate*(x, y: float) =
|
proc translate*(context: Context, x, y: float) {.inline.} =
|
||||||
context.translate(x, y)
|
wrapper.translate(context, x, y)
|
||||||
|
|
||||||
proc rotate*(angle: float) =
|
proc rotate*(context: Context, angle: float) {.inline.} =
|
||||||
context.rotate(angle)
|
wrapper.rotate(context, angle)
|
||||||
|
|
||||||
proc skewX*(angle: float) =
|
proc skewX*(context: Context, angle: float) {.inline.} =
|
||||||
context.skewX(angle)
|
wrapper.skewX(context, angle)
|
||||||
|
|
||||||
proc skewY*(angle: float) =
|
proc skewY*(context: Context, angle: float) {.inline.} =
|
||||||
context.skewY(angle)
|
wrapper.skewY(context, angle)
|
||||||
|
|
||||||
proc scale*(x, y: float) =
|
proc scale*(context: Context, x, y: float) {.inline.} =
|
||||||
context.scale(x, y)
|
wrapper.scale(context, x, y)
|
||||||
|
|
||||||
proc copyArray[T, U](src: T): U =
|
proc copyArray[T, U](src: T): U =
|
||||||
for i in 0..<src.len:
|
for i in 0..<src.len:
|
||||||
result[i] = type(result[i])((src[i]))
|
result[i] = type(result[i])((src[i]))
|
||||||
|
|
||||||
proc getCurrentTransform*(): array[6, float] =
|
proc getCurrentTransform*(context: Context, ): array[6, float] =
|
||||||
var res: array[6, cfloat]
|
var res: array[6, cfloat]
|
||||||
context.currentTransform(res[0].addr)
|
context.currentTransform(res[0].addr)
|
||||||
return copyArray[array[6, cfloat], array[6, float]](res)
|
return copyArray[array[6, cfloat], array[6, float]](res)
|
||||||
|
|
@ -472,7 +507,7 @@ proc degreesToRadians*(degrees: float): float =
|
||||||
proc radiansToDegrees*(radians: float): float =
|
proc radiansToDegrees*(radians: float): float =
|
||||||
return radToDeg(radians)
|
return radToDeg(radians)
|
||||||
|
|
||||||
proc createFrameBuffer*(width, height: float, imageFlags: ImageFlagsGL = ImageFlagsGL.NONE): FrameBuffer =
|
proc createFrameBuffer*(context: Context, width, height: float, imageFlags: ImageFlagsGL = ImageFlagsGL.NONE): FrameBuffer =
|
||||||
return context.createFramebuffer(width.cint, height.cint, imageFlags.cint)
|
return context.createFramebuffer(width.cint, height.cint, imageFlags.cint)
|
||||||
|
|
||||||
proc binde*(fb: FrameBuffer) =
|
proc binde*(fb: FrameBuffer) =
|
||||||
|
|
@ -486,111 +521,101 @@ proc delete*(fb: FrameBuffer) =
|
||||||
proc `or`(imageflags1: ImageFlags, imageflags2: ImageFlags): ImageFlags =
|
proc `or`(imageflags1: ImageFlags, imageflags2: ImageFlags): ImageFlags =
|
||||||
return (imageflags1.cint or imageflags2.cint).ImageFlags
|
return (imageflags1.cint or imageflags2.cint).ImageFlags
|
||||||
|
|
||||||
proc loadImage*(fileName: string, flags: varargs[ImageFlags]): Image =
|
proc loadImage*(context: Context, fileName: string, flags: varargs[ImageFlags]): Image =
|
||||||
var flagArgs = reduce(flags, `or`)
|
var flagArgs = reduce(flags, `or`)
|
||||||
result = context.createImage(fileName, flagArgs.cint)
|
result = context.createImage(fileName, flagArgs.cint)
|
||||||
|
|
||||||
if result == -1:
|
if result == -1:
|
||||||
raise newException(ImageLoadError, fmt"Could not load image {fileName}.")
|
raise newException(ImageLoadError, fmt"Could not load image {fileName}.")
|
||||||
|
|
||||||
macro loadImage*(fileName, flags: string): Image =
|
macro loadImage*(context: Context, fileName, flags: string): Image =
|
||||||
return createExpr("ImageFlags", "loadImage", flags, fileName)
|
return createExpr(context, "ImageFlags", "loadImage", flags, fileName)
|
||||||
|
|
||||||
proc createImageFromArray*(data: openArray[uint8], flags: varargs[ImageFlags]): Image =
|
proc createImageFromArray*(context: Context, data: openArray[uint8], flags: varargs[ImageFlags]): Image =
|
||||||
var flagArgs = reduce(flags, `or`)
|
var flagArgs = reduce(flags, `or`)
|
||||||
result = context.createImageMem(flagArgs.cint, cast[ptr cuchar](data[0].unsafeAddr), data.len.cint)
|
result = context.createImageMem(flagArgs.cint, cast[ptr cuchar](data[0].unsafeAddr), data.len.cint)
|
||||||
|
|
||||||
if result == -1:
|
if result == -1:
|
||||||
raise newException(ImageLoadError, fmt"Could not load image from data.")
|
raise newException(ImageLoadError, fmt"Could not load image from data.")
|
||||||
|
|
||||||
proc size*(image: Image): Size =
|
proc size*(context: Context, image: Image): Size =
|
||||||
var rw, rh: cint
|
var rw, rh: cint
|
||||||
context.imageSize(image, rw.addr, rh.addr)
|
context.imageSize(image, rw.addr, rh.addr)
|
||||||
result.width = rw
|
result.width = rw
|
||||||
result.height = rh
|
result.height = rh
|
||||||
|
|
||||||
proc delete*(image: Image) =
|
export deleteImage
|
||||||
context.deleteImage(image)
|
export beginPath
|
||||||
|
|
||||||
# Paths
|
proc pathMoveTo*(context: Context, x, y: float) =
|
||||||
proc beginPath*() =
|
|
||||||
context.beginPath()
|
|
||||||
|
|
||||||
proc pathMoveTo*(x, y: float) =
|
|
||||||
context.moveTo(x, y)
|
context.moveTo(x, y)
|
||||||
|
|
||||||
proc pathLineTo*(x, y: float) =
|
proc pathLineTo*(context: Context, x, y: float) =
|
||||||
context.lineTo(x, y)
|
context.lineTo(x, y)
|
||||||
|
|
||||||
proc pathBezierTo*(c1x, c1y, c2x, c2y, x, y: float) =
|
proc pathBezierTo*(context: Context, c1x, c1y, c2x, c2y, x, y: float) =
|
||||||
context.bezierTo(c1x, c1y, c2x, c2y, x, y)
|
context.bezierTo(c1x, c1y, c2x, c2y, x, y)
|
||||||
|
|
||||||
proc pathQuadTo*(cx, cy, x, y: float) =
|
proc pathQuadTo*(context: Context, cx, cy, x, y: float) =
|
||||||
context.quadTo(cx, cy, x, y)
|
context.quadTo(cx, cy, x, y)
|
||||||
|
|
||||||
proc pathArcTo*(x1, y1, x2, y2, radius: float) =
|
proc pathArcTo*(context: Context, x1, y1, x2, y2, radius: float) =
|
||||||
context.arcTo(x1, y1, x2, y2, radius)
|
context.arcTo(x1, y1, x2, y2, radius)
|
||||||
|
|
||||||
proc closePath*() =
|
export closePath
|
||||||
context.closePath()
|
|
||||||
|
|
||||||
proc pathWinding*(dir: Winding) =
|
proc pathWinding*(context: Context, dir: Winding) =
|
||||||
context.pathWinding(dir.cint)
|
context.pathWinding(dir.cint)
|
||||||
|
|
||||||
proc setSolidity*(solidity: Solidity) =
|
proc `solidity=`*(context: Context, solidity: Solidity) =
|
||||||
context.pathWinding(solidity.cint)
|
context.pathWinding(solidity.cint)
|
||||||
|
|
||||||
proc pathArc*(cx, cy, r, a0, a1: float, dir: int) =
|
proc pathArc*(context: Context, cx, cy, r, a0, a1: float, dir: int) =
|
||||||
context.arc(cx, cy, r, a0, a1, dir.cint)
|
context.arc(cx, cy, r, a0, a1, dir.cint)
|
||||||
|
|
||||||
proc pathRect*(x, y, width, height: float) =
|
proc pathRect*(context: Context, x, y, width, height: float) =
|
||||||
context.rect(x, y, width, height)
|
context.rect(x, y, width, height)
|
||||||
|
|
||||||
proc pathRoundedRect*(x, y, width, height, radius: float) =
|
proc pathRoundedRect*(context: Context, x, y, width, height, radius: float) =
|
||||||
context.roundedRect(x, y, width, height, radius)
|
context.roundedRect(x, y, width, height, radius)
|
||||||
|
|
||||||
proc pathRoundedRectVarying*(x, y, width, height, radiusTopLeft, radiusTopRight,
|
proc pathRoundedRectVarying*(context: Context, x, y, width, height, radiusTopLeft, radiusTopRight,
|
||||||
radiusBottomRight, radiusBottomLeft: float) =
|
radiusBottomRight, radiusBottomLeft: float) =
|
||||||
context.roundedRectVarying(
|
context.roundedRectVarying(
|
||||||
x, y, width, height,
|
x, y, width, height,
|
||||||
radiusTopLeft, radiusTopRight, radiusBottomRight, radiusBottomLeft
|
radiusTopLeft, radiusTopRight, radiusBottomRight, radiusBottomLeft
|
||||||
)
|
)
|
||||||
|
|
||||||
proc pathEllipse*(cx, cy, radiusX, radiusY: float) =
|
proc pathEllipse*(context: Context, cx, cy, radiusX, radiusY: float) =
|
||||||
context.ellipse(cx, cy, radiusX, radiusY)
|
context.ellipse(cx, cy, radiusX, radiusY)
|
||||||
|
|
||||||
proc pathCircle*(cx, cy, radius: float) =
|
proc pathCircle*(context: Context, cx, cy, radius: float) =
|
||||||
context.circle(cx, cy, radius)
|
context.circle(cx, cy, radius)
|
||||||
|
|
||||||
proc pathFill*() =
|
proc pathFill*(context: Context) =
|
||||||
context.fill()
|
context.fill()
|
||||||
|
|
||||||
proc pathStroke*() =
|
proc pathStroke*(context: Context) =
|
||||||
context.stroke()
|
context.stroke()
|
||||||
|
|
||||||
proc linearGradient*(startX, startY, endX, endY: float, startColor, endColor: Color): Paint =
|
proc linearGradient*(context: Context, startX, startY, endX, endY: float, startColor, endColor: Color): Paint =
|
||||||
result = context.linearGradient(startX, startY, endX, endY, startColor, endColor)
|
result = wrapper.linearGradient(context, startX, startY, endX, endY, startColor, endColor)
|
||||||
|
|
||||||
proc boxGradient*(x, y, width, height, radius, feather: float, startColor, endColor: Color): Paint =
|
proc boxGradient*(context: Context, x, y, width, height, radius, feather: float, startColor, endColor: Color): Paint =
|
||||||
result = context.boxGradient(x, y, width, height, radius, feather, startColor, endColor)
|
result = wrapper.boxGradient(context, x, y, width, height, radius, feather, startColor, endColor)
|
||||||
|
|
||||||
proc radialGradient*(centerX, centerY, innerRadius, outerRadius: float, startColor, endColor: Color): Paint =
|
proc radialGradient*(context: Context, centerX, centerY, innerRadius, outerRadius: float, startColor, endColor: Color): Paint =
|
||||||
result = context.radialGradient(centerX, centerY, innerRadius, outerRadius, startColor, endColor)
|
result = wrapper.radialGradient(context, centerX, centerY, innerRadius, outerRadius, startColor, endColor)
|
||||||
|
|
||||||
proc imagePattern*(originX, originY, renderSizeX, renderSizeY, angle: float, image: Image, alpha: float): Paint =
|
proc imagePattern*(context: Context, originX, originY, renderSizeX, renderSizeY, angle: float, image: Image, alpha: float): Paint =
|
||||||
result = context.imagePattern(originX, originY, renderSizeX, renderSizeY, angle, image, alpha)
|
result = wrapper.imagePattern(context, originX, originY, renderSizeX, renderSizeY, angle, image, alpha)
|
||||||
|
|
||||||
proc setScissor*(x, y, width, height: float) =
|
proc setScissor*(context: Context, x, y, width, height: float) =
|
||||||
context.scissor(x, y, width, height)
|
context.scissor(x, y, width, height)
|
||||||
|
|
||||||
proc intersectScissor*(x, y, width, height: float) =
|
proc intersectScissor*(context: Context, x, y, width, height: float) =
|
||||||
context.intersectScissor(x, y, width, height)
|
context.intersectScissor(x, y, width, height)
|
||||||
|
|
||||||
proc resetScissor*() =
|
proc resetScissor*(context: Context) =
|
||||||
context.resetScissor()
|
context.resetScissor()
|
||||||
|
|
||||||
proc cleanup() {.noconv.} =
|
|
||||||
echo "running cleanup"
|
|
||||||
context.deleteGL3()
|
|
||||||
|
|
||||||
addQuitProc(cleanup)
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue