Skip to content

Commit

Permalink
Fixes #3. Adds Entity Style. Begins work on #6
Browse files Browse the repository at this point in the history
  • Loading branch information
EriKWDev committed Apr 6, 2021
1 parent 891dae4 commit e7a3bca
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 44 deletions.
103 changes: 93 additions & 10 deletions src/nanim/core.nim
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,30 @@ type
AngleMode* = enum
amDegrees, amRadians

StyleMode* = enum
smSolidColor, smPaintPattern, smNone

Style* = ref tuple
fillMode: StyleMode
fillColor: Color
fillPattern: proc(context: NVGContext): Paint

strokeMode: StyleMode
strokeColor: Color
strokePattern: proc(context: NVGContext): Paint
strokeWidth: float

winding: PathWinding
lineCap: LineCapJoin
lineJoin: LineCapJoin
compositeOperation: CompositeOperation

Entity* = ref object of RootObj
points*: seq[Vec3[float]]

tension*: float
cornerRadius*: float
style*: Style

position*: Vec3[float]
rotation*: float
Expand Down Expand Up @@ -58,6 +77,62 @@ type
done*: bool


func newStyle*(): Style =
new(result)
result.fillMode = smPaintPattern
result.fillColor = rgb(255, 56, 116)
result.fillPattern = defaultPattern

result.strokeMode = smSolidColor
result.strokeColor = rgb(230, 26, 94)
result.strokePattern = defaultPattern
result.strokeWidth = 2.0

result.winding = pwCCW
result.lineCap = lcjRound
result.lineJoin = lcjMiter
result.compositeOperation = coSourceOver


proc setStyle*(context: NVGContext, style: Style) =
case style.fillMode:
of smSolidColor:
context.fillColor(style.fillColor)
of smPaintPattern:
context.fillPaint(style.fillPattern(context))
of smNone: discard

context.strokeWidth(style.strokeWidth)
case style.strokeMode:
of smSolidColor:
context.strokeColor(style.strokeColor)
of smPaintPattern:
context.strokePaint(style.strokePattern(context))
of smNone: context.strokeWidth(0.0)

context.pathWinding(style.winding)
context.lineJoin(style.lineJoin)
context.lineCap(style.lineCap)
context.globalCompositeOperation(style.compositeOperation)


proc executeStyle*(context: NVGContext, style: Style) =
case style.fillMode:
of smSolidColor, smPaintPattern:
context.fill()
of smNone: discard

case style.strokeMode:
of smSolidColor, smPaintPattern:
context.stroke()
of smNone: discard


proc applyStyle*(context: NVGContext, style: Style) =
context.setStyle(style)
context.executeStyle(style)


const
defaultTrackId* = 0
defaultAngleMode*: AngleMode = amDegrees
Expand All @@ -75,26 +150,22 @@ proc `$`*(entity: Entity): string =

method draw*(entity: Entity, scene: Scene) {.base.} =
let context = scene.context
context.beginPath()
context.save()

context.beginPath()
if entity.tension > 0:
context.drawPointsWithTension(entity.points, entity.tension)
else:
context.drawPointsWithRoundedCornerRadius(entity.points, entity.cornerRadius)

context.closePath()

# context.fillColor(rgb(255, 56, 116))
context.fillPaint(context.gridPattern())
context.fill()

context.strokeColor(rgb(230, 26, 94))
context.strokeWidth(5)
context.stroke()
context.applyStyle(entity.style)
context.restore()


func init*(entity: Entity) =
entity.points = @[]
entity.style = newStyle()
entity.children = @[]
entity.tension = 0.0
entity.cornerRadius = 20.0
Expand Down Expand Up @@ -343,6 +414,16 @@ proc setCornerRadius*(entity: Entity, cornerRadius: float = 0.0): Tween =
result = newTween(interpolators)


proc fill(context: NVGContext, width: cfloat, height: cfloat, color: Color = rgb(255, 255, 255)) =
context.save()
context.fillColor(color)
context.beginPath()
context.resetTransform()
context.rect(0, 0, width, height)
context.closePath()
context.fill()
context.restore()

proc init(scene: Scene) =
scene.time = 0.0
scene.restartTime = 0.0
Expand All @@ -356,7 +437,9 @@ proc init(scene: Scene) =
vec4[float](0,0,1,0),
vec4[float](0,0,0,1))
scene.done = false
scene.background = proc(scene: Scene) = clearWithColor(rgb(255, 255, 255))
scene.background =
proc(scene: Scene) = scene.context.fill(scene.width.cfloat, scene.height.cfloat, rgb(255, 255, 255))

scene.foreground = proc(scene: Scene) = discard


Expand Down
63 changes: 38 additions & 25 deletions src/nanim/drawing.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import
nanovg,
opengl,
glfw,
glm


Expand Down Expand Up @@ -57,9 +58,9 @@ proc drawPointsWithRoundedCornerRadius*(context: NVGContext, points: seq[Vec], c
context.arcTo(p1.x, p1.y, midPoint.x, midPoint.y, cornerRadius)


proc defaultPattern(context: NVGContext) =
proc defaultPatternDrawer(context: NVGContext, width: float, height: float) =
context.beginPath()
context.circle(5, 1440-5, 3)
context.circle(width/2, height/2, width/2)
context.closePath()

context.fillColor(rgb(20, 20, 20))
Expand All @@ -70,45 +71,57 @@ var
patternPaint: Paint
hasGatheredPattern = false

proc gridPattern*(context: NVGContext, patternDrawer: proc(context: NVGContext) = defaultPattern, width: cint = 10, height: cint = 10): Paint =

proc offset(some: pointer; b: int): pointer {.inline.} =
result = cast[pointer](cast[int](some) + b)


proc gridPattern*(context: NVGContext, patternDrawer: proc(context: NVGContext, width: float, height: float) = defaultPatternDrawer, width: cint = 10, height: cint = 10): Paint =
# Impure, but worth it for the performance benefit...
if hasGatheredPattern:
return patternPaint

let
bufferSize = width*height*4
oldTransformMatrix = context.currentTransform()
bufferSize = width * height * 4
tempContext = nvgCreateContext({nifStencilStrokes, nifDebug})

var
oldData = alloc0(bufferSize)
imageData = alloc0(bufferSize)
var imageData = alloc0(bufferSize)

context.endFrame()

glPixelStorei(GL_PACK_ALIGNMENT, 1)
glReadBuffer(GL_BACK)

glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, oldData)
# clear the region
glDrawPixels(width, height, GL_RGBA, GL_UNSIGNED_BYTE, imageData)

context.beginFrame(2880.cfloat, 1440.cfloat, 1)
patternDrawer(context)
context.endFrame()
# draw the pattern
let
window = currentContext()
(frameBufferWidth, frameBufferHeight) = window.framebufferSize

tempContext.beginFrame(frameBufferWidth.cfloat, frameBufferHeight.cfloat, 1)
clearWithColor()
tempContext.translate(0, frameBufferHeight.float - height.float)
patternDrawer(tempContext, width.float, height.float)
tempContext.endFrame()

# read the region
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, imageData)
var pixels: seq[uint8] = newSeq[uint8](bufferSize)
copyMem(pixels[0].unsafeAddr, imageData, bufferSize)

var pixels = newSeq[uint8](bufferSize)

# Flip the image
for y in 0..<height:
let
lineSize = width * 4
yDest = y * lineSize
ySrc = bufferSize - yDest - lineSize
copyMem(pixels[yDest].unsafeAddr, imageData.offset(ySrc), lineSize)

let image = context.createImageRGBA(width, height, {ifRepeatX, ifRepeatY, ifFlipY}, pixels)

patternPaint = context.imagePattern(0, 0, width.cfloat, height.cfloat, 0, image, 1.0)
hasGatheredPattern = true
result = patternPaint

context.beginFrame(2880.cfloat, 1440.cfloat, 1)
glDrawPixels(width, height, GL_RGBA, GL_UNSIGNED_BYTE, oldData)

dealloc(oldData)
dealloc(imageData)

context.transform(oldTransformMatrix.m[0], oldTransformMatrix.m[1], oldTransformMatrix.m[2],
oldTransformMatrix.m[3], oldTransformMatrix.m[4], oldTransformMatrix.m[5])

proc defaultPattern*(context: NVGContext): Paint =
context.gridPattern(defaultPatternDrawer, 10, 10)
11 changes: 3 additions & 8 deletions src/nanim/entities/text.nim
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type
proc init*(text: Text) =
init(text.Entity)
text.message = ""
text.style.fillMode = smSolidColor


method draw*(text: Text, scene: Scene) =
Expand All @@ -24,17 +25,11 @@ method draw*(text: Text, scene: Scene) =
context.fontSize(text.fontSize * 10)
context.fontFace(text.font)

context.beginPath()

context.fillColor(rgb(255, 56, 116))

context.strokeColor(rgb(230, 26, 94))
context.strokeWidth(20)
context.setStyle(text.style)

context.beginPath()
discard context.text(0, 0, text.message)
context.closePath()
context.stroke()
context.fill()


proc newText*(message: string = "",
Expand Down
2 changes: 2 additions & 0 deletions src/nanim/rendering.nim
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ proc setupRendering(userScene: Scene, resizable: bool = true, width: int = 1920,
doAssert glInit()

glEnable(GL_MULTISAMPLE)
glEnable(GL_BLEND)
# glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

makeContextCurrent(scene.window)

Expand Down
3 changes: 2 additions & 1 deletion tests/nim.cfg
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
--path:"../src/"
--path:"../src/"
-d:glfwStaticLib

0 comments on commit e7a3bca

Please sign in to comment.