rm realtime examples, suggest better approach with boxy
This commit is contained in:
parent
bde0d2fd5c
commit
e6c799a04f
7 changed files with 2 additions and 577 deletions
|
@ -99,14 +99,9 @@ Q q T t | ✅ | quadratic to |
|
||||||
A a | ✅ | arc to |
|
A a | ✅ | arc to |
|
||||||
z | ✅ | close path |
|
z | ✅ | close path |
|
||||||
|
|
||||||
### Realtime Examples
|
### Pixie + GPU
|
||||||
|
|
||||||
Here are some examples of using Pixie for realtime rendering with some popular windowing libraries:
|
To learn how to use Pixie for realtime graphics with GPU, check out [Boxy](https://github.com/treeform/boxy).
|
||||||
|
|
||||||
* [examples/realtime_glfw.nim](examples/realtime_glfw.nim)
|
|
||||||
* [examples/realtime_glut.nim](examples/realtime_glut.nim)
|
|
||||||
* [examples/realtime_sdl.nim](examples/realtime_sdl.nim)
|
|
||||||
* [examples/realtime_win32.nim](examples/realtime_win32.nim)
|
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
|
|
|
@ -1,81 +0,0 @@
|
||||||
## This example show how to have real time pixie using glfw API.
|
|
||||||
|
|
||||||
import math, opengl, pixie, staticglfw
|
|
||||||
|
|
||||||
let
|
|
||||||
w: int32 = 256
|
|
||||||
h: int32 = 256
|
|
||||||
|
|
||||||
var
|
|
||||||
screen = newImage(w, h)
|
|
||||||
ctx = newContext(screen)
|
|
||||||
frameCount = 0
|
|
||||||
window: Window
|
|
||||||
|
|
||||||
proc display() =
|
|
||||||
## Called every frame by main while loop
|
|
||||||
|
|
||||||
# draw shiny sphere on gradient background
|
|
||||||
let linerGradient = newPaint(pkGradientLinear)
|
|
||||||
linerGradient.gradientHandlePositions.add(vec2(0, 0))
|
|
||||||
linerGradient.gradientHandlePositions.add(vec2(0, 256))
|
|
||||||
linerGradient.gradientStops.add(
|
|
||||||
ColorStop(color: color(0, 0, 0, 1), position: 0))
|
|
||||||
linerGradient.gradientStops.add(
|
|
||||||
ColorStop(color: color(1, 1, 1, 1), position: 1))
|
|
||||||
ctx.fillStyle = linerGradient
|
|
||||||
ctx.fillRect(0, 0, 256, 256)
|
|
||||||
|
|
||||||
let radialGradient = newPaint(pkGradientRadial)
|
|
||||||
radialGradient.gradientHandlePositions.add(vec2(128, 128))
|
|
||||||
radialGradient.gradientHandlePositions.add(vec2(256, 128))
|
|
||||||
radialGradient.gradientHandlePositions.add(vec2(128, 256))
|
|
||||||
radialGradient.gradientStops.add(
|
|
||||||
ColorStop(color: color(1, 1, 1, 1), position: 0))
|
|
||||||
radialGradient.gradientStops.add(
|
|
||||||
ColorStop(color: color(0, 0, 0, 1), position: 1))
|
|
||||||
ctx.fillStyle = radialGradient
|
|
||||||
ctx.fillCircle(circle(
|
|
||||||
vec2(128.0, 128.0 + sin(float32(frameCount)/10.0) * 20),
|
|
||||||
76.8
|
|
||||||
))
|
|
||||||
|
|
||||||
# update texture with new pixels from surface
|
|
||||||
var dataPtr = ctx.image.data[0].addr
|
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GLsizei w, GLsizei h, GL_RGBA,
|
|
||||||
GL_UNSIGNED_BYTE, dataPtr)
|
|
||||||
|
|
||||||
# draw a quad over the whole screen
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT)
|
|
||||||
glBegin(GL_QUADS)
|
|
||||||
glTexCoord2d(0.0, 0.0); glVertex2d(-1.0, +1.0)
|
|
||||||
glTexCoord2d(1.0, 0.0); glVertex2d(+1.0, +1.0)
|
|
||||||
glTexCoord2d(1.0, 1.0); glVertex2d(+1.0, -1.0)
|
|
||||||
glTexCoord2d(0.0, 1.0); glVertex2d(-1.0, -1.0)
|
|
||||||
glEnd()
|
|
||||||
|
|
||||||
inc frameCount
|
|
||||||
swapBuffers(window)
|
|
||||||
|
|
||||||
if init() == 0:
|
|
||||||
quit("Failed to Initialize GLFW.")
|
|
||||||
|
|
||||||
windowHint(RESIZABLE, false.cint)
|
|
||||||
window = createWindow(w.cint, h.cint, "GLFW/Pixie", nil, nil)
|
|
||||||
|
|
||||||
makeContextCurrent(window)
|
|
||||||
loadExtensions()
|
|
||||||
|
|
||||||
# allocate a texture and bind it
|
|
||||||
var dataPtr = ctx.image.data[0].addr
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, 3, GLsizei w, GLsizei h, 0, GL_RGBA,
|
|
||||||
GL_UNSIGNED_BYTE, dataPtr)
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
|
|
||||||
glEnable(GL_TEXTURE_2D)
|
|
||||||
|
|
||||||
while windowShouldClose(window) != 1:
|
|
||||||
pollEvents()
|
|
||||||
display()
|
|
|
@ -1,78 +0,0 @@
|
||||||
## This example show how to have real time pixie using glut API.
|
|
||||||
|
|
||||||
import math, opengl, opengl/glu, opengl/glut, pixie
|
|
||||||
|
|
||||||
let
|
|
||||||
w: int32 = 256
|
|
||||||
h: int32 = 256
|
|
||||||
|
|
||||||
var
|
|
||||||
screen = newImage(w, h)
|
|
||||||
ctx = newContext(screen)
|
|
||||||
frameCount = 0
|
|
||||||
|
|
||||||
proc display() {.cdecl.} =
|
|
||||||
## Called every frame by GLUT
|
|
||||||
|
|
||||||
# draw shiny sphere on gradient background
|
|
||||||
let linerGradient = newPaint(pkGradientLinear)
|
|
||||||
linerGradient.gradientHandlePositions.add(vec2(0, 0))
|
|
||||||
linerGradient.gradientHandlePositions.add(vec2(0, 256))
|
|
||||||
linerGradient.gradientStops.add(
|
|
||||||
ColorStop(color: color(0, 0, 0, 1), position: 0))
|
|
||||||
linerGradient.gradientStops.add(
|
|
||||||
ColorStop(color: color(1, 1, 1, 1), position: 1))
|
|
||||||
ctx.fillStyle = linerGradient
|
|
||||||
ctx.fillRect(0, 0, 256, 256)
|
|
||||||
|
|
||||||
let radialGradient = newPaint(pkGradientRadial)
|
|
||||||
radialGradient.gradientHandlePositions.add(vec2(128, 128))
|
|
||||||
radialGradient.gradientHandlePositions.add(vec2(256, 128))
|
|
||||||
radialGradient.gradientHandlePositions.add(vec2(128, 256))
|
|
||||||
radialGradient.gradientStops.add(
|
|
||||||
ColorStop(color: color(1, 1, 1, 1), position: 0))
|
|
||||||
radialGradient.gradientStops.add(
|
|
||||||
ColorStop(color: color(0, 0, 0, 1), position: 1))
|
|
||||||
ctx.fillStyle = radialGradient
|
|
||||||
ctx.fillCircle(circle(
|
|
||||||
vec2(128.0, 128.0 + sin(float32(frameCount)/10.0) * 20),
|
|
||||||
76.8
|
|
||||||
))
|
|
||||||
# update texture with new pixels from surface
|
|
||||||
var dataPtr = ctx.image.data[0].addr
|
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GLsizei w, GLsizei h, GL_RGBA,
|
|
||||||
GL_UNSIGNED_BYTE, dataPtr)
|
|
||||||
|
|
||||||
# draw a quad over the whole screen
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT)
|
|
||||||
glBegin(GL_QUADS)
|
|
||||||
glTexCoord2d(0.0, 0.0); glVertex2d(-1.0, +1.0)
|
|
||||||
glTexCoord2d(1.0, 0.0); glVertex2d(+1.0, +1.0)
|
|
||||||
glTexCoord2d(1.0, 1.0); glVertex2d(+1.0, -1.0)
|
|
||||||
glTexCoord2d(0.0, 1.0); glVertex2d(-1.0, -1.0)
|
|
||||||
glEnd()
|
|
||||||
glutSwapBuffers()
|
|
||||||
|
|
||||||
inc frameCount
|
|
||||||
|
|
||||||
glutPostRedisplay() # ask glut to draw next frame
|
|
||||||
|
|
||||||
glutInit()
|
|
||||||
glutInitDisplayMode(GLUT_DOUBLE)
|
|
||||||
glutInitWindowSize(w, h)
|
|
||||||
discard glutCreateWindow("GLUT/Pixie")
|
|
||||||
|
|
||||||
glutDisplayFunc(display)
|
|
||||||
loadExtensions()
|
|
||||||
|
|
||||||
# allocate a texture and bind it
|
|
||||||
var dataPtr = ctx.image.data[0].addr
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, 3, GLsizei w, GLsizei h, 0, GL_RGBA,
|
|
||||||
GL_UNSIGNED_BYTE, dataPtr)
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
|
|
||||||
glEnable(GL_TEXTURE_2D)
|
|
||||||
|
|
||||||
glutMainLoop()
|
|
|
@ -1,75 +0,0 @@
|
||||||
## This example show how to have real time pixie using sdl2 API.
|
|
||||||
|
|
||||||
import math, pixie, sdl2, sdl2/gfx
|
|
||||||
|
|
||||||
const
|
|
||||||
rmask = uint32 0x000000ff
|
|
||||||
gmask = uint32 0x0000ff00
|
|
||||||
bmask = uint32 0x00ff0000
|
|
||||||
amask = uint32 0xff000000
|
|
||||||
|
|
||||||
let
|
|
||||||
w: int32 = 256
|
|
||||||
h: int32 = 256
|
|
||||||
|
|
||||||
var
|
|
||||||
screen = newImage(w, h)
|
|
||||||
ctx = newContext(screen)
|
|
||||||
frameCount = 0
|
|
||||||
window: WindowPtr
|
|
||||||
render: RendererPtr
|
|
||||||
mainSurface: SurfacePtr
|
|
||||||
mainTexture: TexturePtr
|
|
||||||
evt = sdl2.defaultEvent
|
|
||||||
|
|
||||||
proc display() =
|
|
||||||
## Called every frame by main while loop
|
|
||||||
|
|
||||||
# draw shiny sphere on gradient background
|
|
||||||
let linerGradient = newPaint(pkGradientLinear)
|
|
||||||
linerGradient.gradientHandlePositions.add(vec2(0, 0))
|
|
||||||
linerGradient.gradientHandlePositions.add(vec2(0, 256))
|
|
||||||
linerGradient.gradientStops.add(
|
|
||||||
ColorStop(color: pixie.color(0, 0, 0, 1), position: 0))
|
|
||||||
linerGradient.gradientStops.add(
|
|
||||||
ColorStop(color: pixie.color(1, 1, 1, 1), position: 1))
|
|
||||||
ctx.fillStyle = linerGradient
|
|
||||||
ctx.fillRect(0, 0, 256, 256)
|
|
||||||
|
|
||||||
let radialGradient = newPaint(pkGradientRadial)
|
|
||||||
radialGradient.gradientHandlePositions.add(vec2(128, 128))
|
|
||||||
radialGradient.gradientHandlePositions.add(vec2(256, 128))
|
|
||||||
radialGradient.gradientHandlePositions.add(vec2(128, 256))
|
|
||||||
radialGradient.gradientStops.add(
|
|
||||||
ColorStop(color: pixie.color(1, 1, 1, 1), position: 0))
|
|
||||||
radialGradient.gradientStops.add(
|
|
||||||
ColorStop(color: pixie.color(0, 0, 0, 1), position: 1))
|
|
||||||
ctx.fillStyle = radialGradient
|
|
||||||
ctx.fillCircle(circle(
|
|
||||||
vec2(128.0, 128.0 + sin(float32(frameCount)/10.0) * 20),
|
|
||||||
76.8
|
|
||||||
))
|
|
||||||
inc frameCount
|
|
||||||
|
|
||||||
var dataPtr = ctx.image.data[0].addr
|
|
||||||
mainSurface = createRGBSurfaceFrom(dataPtr, cint w, cint h, cint 32, cint 4*w,
|
|
||||||
rmask, gmask, bmask, amask)
|
|
||||||
mainTexture = render.createTextureFromSurface(mainSurface)
|
|
||||||
destroy(mainSurface)
|
|
||||||
|
|
||||||
render.clear()
|
|
||||||
render.copy(mainTexture, nil, nil)
|
|
||||||
destroy(mainTexture)
|
|
||||||
|
|
||||||
render.present()
|
|
||||||
|
|
||||||
discard sdl2.init(INIT_EVERYTHING)
|
|
||||||
window = createWindow("SDL/Pixie", 100, 100, cint w, cint h, SDL_WINDOW_SHOWN)
|
|
||||||
render = createRenderer(window, -1, 0)
|
|
||||||
|
|
||||||
while true:
|
|
||||||
while pollEvent(evt):
|
|
||||||
if evt.kind == QuitEvent:
|
|
||||||
quit(0)
|
|
||||||
display()
|
|
||||||
delay(14)
|
|
|
@ -1,144 +0,0 @@
|
||||||
## This example show how to have real time pixie using win32 API.
|
|
||||||
|
|
||||||
import pixie, winim/lean
|
|
||||||
|
|
||||||
let
|
|
||||||
w: int32 = 256
|
|
||||||
h: int32 = 256
|
|
||||||
|
|
||||||
var
|
|
||||||
screen = newImage(w, h)
|
|
||||||
ctx = newContext(screen)
|
|
||||||
frameCount = 0
|
|
||||||
hwnd: HWND
|
|
||||||
running = true
|
|
||||||
|
|
||||||
proc draw() =
|
|
||||||
# draw shiny sphere on gradient background
|
|
||||||
let linerGradient = newPaint(pkGradientLinear)
|
|
||||||
linerGradient.gradientHandlePositions.add(vec2(0, 0))
|
|
||||||
linerGradient.gradientHandlePositions.add(vec2(0, 256))
|
|
||||||
linerGradient.gradientStops.add(
|
|
||||||
ColorStop(color: color(0, 0, 0, 1), position: 0))
|
|
||||||
linerGradient.gradientStops.add(
|
|
||||||
ColorStop(color: color(1, 1, 1, 1), position: 1))
|
|
||||||
ctx.fillStyle = linerGradient
|
|
||||||
ctx.fillRect(0, 0, 256, 256)
|
|
||||||
|
|
||||||
let radialGradient = newPaint(pkGradientRadial)
|
|
||||||
radialGradient.gradientHandlePositions.add(vec2(128, 128))
|
|
||||||
radialGradient.gradientHandlePositions.add(vec2(256, 128))
|
|
||||||
radialGradient.gradientHandlePositions.add(vec2(128, 256))
|
|
||||||
radialGradient.gradientStops.add(
|
|
||||||
ColorStop(color: color(1, 1, 1, 1), position: 0))
|
|
||||||
radialGradient.gradientStops.add(
|
|
||||||
ColorStop(color: color(0, 0, 0, 1), position: 1))
|
|
||||||
ctx.fillStyle = radialGradient
|
|
||||||
ctx.fillCircle(circle(
|
|
||||||
vec2(128.0, 128.0 + sin(float32(frameCount)/10.0) * 20),
|
|
||||||
76.8
|
|
||||||
))
|
|
||||||
|
|
||||||
inc frameCount
|
|
||||||
|
|
||||||
# Draw image pixels onto win32 window.
|
|
||||||
let
|
|
||||||
w = screen.width.int32
|
|
||||||
h = screen.height.int32
|
|
||||||
dc = GetDC(hwnd)
|
|
||||||
var info = BITMAPINFO()
|
|
||||||
info.bmiHeader.biBitCount = 32
|
|
||||||
info.bmiHeader.biWidth = w
|
|
||||||
info.bmiHeader.biHeight = h
|
|
||||||
info.bmiHeader.biPlanes = 1
|
|
||||||
info.bmiHeader.biSize = DWORD sizeof(BITMAPINFOHEADER)
|
|
||||||
info.bmiHeader.biSizeImage = w * h * 4
|
|
||||||
info.bmiHeader.biCompression = BI_RGB
|
|
||||||
var bgrBuffer = newSeq[uint8](screen.data.len * 4)
|
|
||||||
# Convert to BGRA.
|
|
||||||
for i, c in screen.data:
|
|
||||||
bgrBuffer[i*4+0] = c.b
|
|
||||||
bgrBuffer[i*4+1] = c.g
|
|
||||||
bgrBuffer[i*4+2] = c.r
|
|
||||||
discard StretchDIBits(
|
|
||||||
dc,
|
|
||||||
0,
|
|
||||||
h - 1,
|
|
||||||
w,
|
|
||||||
-h,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
w,
|
|
||||||
h,
|
|
||||||
bgrBuffer[0].addr,
|
|
||||||
info,
|
|
||||||
DIB_RGB_COLORS,
|
|
||||||
SRCCOPY
|
|
||||||
)
|
|
||||||
discard ReleaseDC(hwnd, dc)
|
|
||||||
|
|
||||||
proc windowProc(hwnd: HWND, message: UINT, wParam: WPARAM,
|
|
||||||
lParam: LPARAM): LRESULT {.stdcall.} =
|
|
||||||
case message
|
|
||||||
of WM_DESTROY:
|
|
||||||
PostQuitMessage(0)
|
|
||||||
running = false
|
|
||||||
return 0
|
|
||||||
else:
|
|
||||||
return DefWindowProc(hwnd, message, wParam, lParam)
|
|
||||||
|
|
||||||
proc main() =
|
|
||||||
var
|
|
||||||
hInstance = GetModuleHandle(nil)
|
|
||||||
appName = "Win32/Pixie"
|
|
||||||
msg: MSG
|
|
||||||
wndclass: WNDCLASS
|
|
||||||
|
|
||||||
wndclass.style = CS_HREDRAW or CS_VREDRAW
|
|
||||||
wndclass.lpfnWndProc = windowProc
|
|
||||||
wndclass.cbClsExtra = 0
|
|
||||||
wndclass.cbWndExtra = 0
|
|
||||||
wndclass.hInstance = hInstance
|
|
||||||
wndclass.hIcon = LoadIcon(0, IDI_APPLICATION)
|
|
||||||
wndclass.hCursor = LoadCursor(0, IDC_ARROW)
|
|
||||||
wndclass.hbrBackground = GetStockObject(WHITE_BRUSH)
|
|
||||||
wndclass.lpszMenuName = nil
|
|
||||||
wndclass.lpszClassName = appName
|
|
||||||
|
|
||||||
if RegisterClass(wndclass) == 0:
|
|
||||||
MessageBox(0, "This program requires Windows NT!", appName, MB_ICONERROR)
|
|
||||||
return
|
|
||||||
|
|
||||||
# Figure out the right size of the window we want.
|
|
||||||
var rect: lean.RECT
|
|
||||||
rect.left = 0
|
|
||||||
rect.top = 0
|
|
||||||
rect.right = w
|
|
||||||
rect.bottom = h
|
|
||||||
AdjustWindowRectEx(cast[LPRECT](rect.addr), WS_OVERLAPPEDWINDOW, 0, 0)
|
|
||||||
|
|
||||||
# Open the window.
|
|
||||||
hwnd = CreateWindow(
|
|
||||||
appName,
|
|
||||||
"Win32/Pixie",
|
|
||||||
WS_OVERLAPPEDWINDOW,
|
|
||||||
CW_USEDEFAULT,
|
|
||||||
CW_USEDEFAULT,
|
|
||||||
rect.right - rect.left,
|
|
||||||
rect.bottom - rect.top,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
hInstance,
|
|
||||||
nil
|
|
||||||
)
|
|
||||||
|
|
||||||
ShowWindow(hwnd, SW_SHOW)
|
|
||||||
UpdateWindow(hwnd)
|
|
||||||
|
|
||||||
while running:
|
|
||||||
draw()
|
|
||||||
PeekMessage(msg, 0, 0, 0, PM_REMOVE)
|
|
||||||
TranslateMessage(msg)
|
|
||||||
DispatchMessage(msg)
|
|
||||||
|
|
||||||
main()
|
|
|
@ -1,72 +0,0 @@
|
||||||
import pixie, wNim/wApp, wNim/wFrame, wNim/wImage, wNim/wPaintDC
|
|
||||||
|
|
||||||
let
|
|
||||||
w = 256
|
|
||||||
h = 256
|
|
||||||
|
|
||||||
var
|
|
||||||
screen = newImage(w, h)
|
|
||||||
ctx = newContext(screen)
|
|
||||||
frameCount = 0
|
|
||||||
image = Image(w, h)
|
|
||||||
app = App()
|
|
||||||
frame = Frame(title = "wNim/Pixie")
|
|
||||||
|
|
||||||
proc draw() =
|
|
||||||
# draw shiny sphere on gradient background
|
|
||||||
let linerGradient = newPaint(pkGradientLinear)
|
|
||||||
linerGradient.gradientHandlePositions.add(vec2(0, 0))
|
|
||||||
linerGradient.gradientHandlePositions.add(vec2(0, 256))
|
|
||||||
linerGradient.gradientStops.add(
|
|
||||||
ColorStop(color: color(0, 0, 0, 1), position: 0))
|
|
||||||
linerGradient.gradientStops.add(
|
|
||||||
ColorStop(color: color(1, 1, 1, 1), position: 1))
|
|
||||||
ctx.fillStyle = linerGradient
|
|
||||||
ctx.fillRect(0, 0, 256, 256)
|
|
||||||
|
|
||||||
let radialGradient = newPaint(pkGradientRadial)
|
|
||||||
radialGradient.gradientHandlePositions.add(vec2(128, 128))
|
|
||||||
radialGradient.gradientHandlePositions.add(vec2(256, 128))
|
|
||||||
radialGradient.gradientHandlePositions.add(vec2(128, 256))
|
|
||||||
radialGradient.gradientStops.add(
|
|
||||||
ColorStop(color: color(1, 1, 1, 1), position: 0))
|
|
||||||
radialGradient.gradientStops.add(
|
|
||||||
ColorStop(color: color(0, 0, 0, 1), position: 1))
|
|
||||||
ctx.fillStyle = radialGradient
|
|
||||||
ctx.fillCircle(circle(
|
|
||||||
vec2(128.0, 128.0 + sin(float32(frameCount)/10.0) * 20),
|
|
||||||
76.8
|
|
||||||
))
|
|
||||||
inc frameCount
|
|
||||||
|
|
||||||
proc render() =
|
|
||||||
|
|
||||||
proc GdipCreateBitmapFromScan0(width: cint, height: cint, stride: cint,
|
|
||||||
format: cint, scan0: pointer, bitmap: pointer): cint
|
|
||||||
{.stdcall, discardable, dynlib: "gdiplus", importc.}
|
|
||||||
|
|
||||||
proc GdipDisposeImage(image: pointer): cint
|
|
||||||
{.stdcall, discardable, dynlib: "gdiplus", importc.}
|
|
||||||
|
|
||||||
const PixelFormat32bppARGB = 2498570
|
|
||||||
|
|
||||||
GdipDisposeImage(image.mGdipBmp)
|
|
||||||
|
|
||||||
GdipCreateBitmapFromScan0(cint w, cint h, cint w * 4,
|
|
||||||
PixelFormat32bppARGB, ctx.image.data[0].addr, addr image.mGdipBmp)
|
|
||||||
|
|
||||||
frame.clientSize = (w, h)
|
|
||||||
|
|
||||||
frame.startTimer(0.01)
|
|
||||||
|
|
||||||
frame.wEvent_Timer do ():
|
|
||||||
draw()
|
|
||||||
render()
|
|
||||||
frame.refresh(false)
|
|
||||||
|
|
||||||
frame.wEvent_Paint do ():
|
|
||||||
var dc = PaintDC(frame)
|
|
||||||
dc.drawImage(image)
|
|
||||||
|
|
||||||
frame.show()
|
|
||||||
app.mainLoop()
|
|
|
@ -1,120 +0,0 @@
|
||||||
## This example show how to have real time pixie using the X11 API.
|
|
||||||
|
|
||||||
import math, pixie, std/os
|
|
||||||
import
|
|
||||||
x11/xlib,
|
|
||||||
x11/xutil,
|
|
||||||
x11/x
|
|
||||||
|
|
||||||
let
|
|
||||||
w: int32 = 256
|
|
||||||
h: int32 = 256
|
|
||||||
|
|
||||||
var
|
|
||||||
screen = newImage(w, h)
|
|
||||||
ctx = newContext(screen)
|
|
||||||
|
|
||||||
var
|
|
||||||
display: PDisplay
|
|
||||||
window: Window
|
|
||||||
deleteMessage: Atom
|
|
||||||
graphicsContext: GC
|
|
||||||
frameCount = 0
|
|
||||||
|
|
||||||
proc render() =
|
|
||||||
## Called every frame by main while loop
|
|
||||||
|
|
||||||
# draw shiny sphere on gradient background
|
|
||||||
let linerGradient = newPaint(pkGradientLinear)
|
|
||||||
linerGradient.gradientHandlePositions.add(vec2(0, 0))
|
|
||||||
linerGradient.gradientHandlePositions.add(vec2(0, 256))
|
|
||||||
linerGradient.gradientStops.add(
|
|
||||||
ColorStop(color: pixie.color(0, 0, 0, 1), position: 0))
|
|
||||||
linerGradient.gradientStops.add(
|
|
||||||
ColorStop(color: pixie.color(1, 1, 1, 1), position: 1))
|
|
||||||
ctx.fillStyle = linerGradient
|
|
||||||
ctx.fillRect(0, 0, 256, 256)
|
|
||||||
let radialGradient = newPaint(pkGradientRadial)
|
|
||||||
radialGradient.gradientHandlePositions.add(vec2(128, 128))
|
|
||||||
radialGradient.gradientHandlePositions.add(vec2(256, 128))
|
|
||||||
radialGradient.gradientHandlePositions.add(vec2(128, 256))
|
|
||||||
radialGradient.gradientStops.add(
|
|
||||||
ColorStop(color: pixie.color(1, 1, 1, 1), position: 0))
|
|
||||||
radialGradient.gradientStops.add(
|
|
||||||
ColorStop(color: pixie.color(0, 0, 0, 1), position: 1))
|
|
||||||
ctx.fillStyle = radialGradient
|
|
||||||
ctx.fillCircle(circle(
|
|
||||||
vec2(128.0, 128.0 + sin(float32(frameCount)/10.0) * 20),
|
|
||||||
76.8
|
|
||||||
))
|
|
||||||
inc frameCount
|
|
||||||
var frameBuffer = addr ctx.image.data[0]
|
|
||||||
let image = XCreateImage(display, DefaultVisualOfScreen(
|
|
||||||
DefaultScreenOfDisplay(display)), 24, ZPixmap, 0, cast[cstring](
|
|
||||||
frameBuffer), w.cuint, h.cuint, 8, w*4)
|
|
||||||
discard XPutImage(display, window, graphicsContext, image, 0, 0, 0, 0, w.cuint, h.cuint)
|
|
||||||
|
|
||||||
const
|
|
||||||
borderWidth = 0
|
|
||||||
eventMask = ButtonPressMask or KeyPressMask or ExposureMask
|
|
||||||
|
|
||||||
proc init() =
|
|
||||||
display = XOpenDisplay(nil)
|
|
||||||
if display == nil:
|
|
||||||
quit "Failed to open display"
|
|
||||||
|
|
||||||
let
|
|
||||||
screen = XDefaultScreen(display)
|
|
||||||
rootWindow = XRootWindow(display, screen)
|
|
||||||
foregroundColor = XBlackPixel(display, screen)
|
|
||||||
backgroundColor = XWhitePixel(display, screen)
|
|
||||||
|
|
||||||
window = XCreateSimpleWindow(display, rootWindow, -1, -1, w.cuint, h.cuint,
|
|
||||||
borderWidth, foregroundColor, backgroundColor)
|
|
||||||
|
|
||||||
|
|
||||||
discard XSetStandardProperties(display, window, "X11 Example", "window", 0,
|
|
||||||
nil, 0, nil)
|
|
||||||
|
|
||||||
discard XSelectInput(display, window, eventMask)
|
|
||||||
discard XMapWindow(display, window)
|
|
||||||
|
|
||||||
deleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", false.XBool)
|
|
||||||
discard XSetWMProtocols(display, window, deleteMessage.addr, 1)
|
|
||||||
|
|
||||||
graphicsContext = XDefaultGC(display, screen)
|
|
||||||
|
|
||||||
|
|
||||||
proc mainLoop() =
|
|
||||||
## Process events until the quit event is received
|
|
||||||
var event: XEvent
|
|
||||||
var exposed: bool = false
|
|
||||||
while true:
|
|
||||||
if exposed: render()
|
|
||||||
if XPending(display) > 0:
|
|
||||||
discard XNextEvent(display, event.addr)
|
|
||||||
case event.theType
|
|
||||||
of Expose:
|
|
||||||
render()
|
|
||||||
exposed = true
|
|
||||||
of ClientMessage:
|
|
||||||
if cast[Atom](event.xclient.data.l[0]) == deleteMessage:
|
|
||||||
break
|
|
||||||
of KeyPress:
|
|
||||||
let key = XLookupKeysym(cast[PXKeyEvent](event.addr), 0)
|
|
||||||
if key != 0:
|
|
||||||
echo "Key ", key, " pressed"
|
|
||||||
of ButtonPressMask:
|
|
||||||
echo "Mouse button ", event.xbutton.button, " pressed at ",
|
|
||||||
event.xbutton.x, ",", event.xbutton.y
|
|
||||||
else:
|
|
||||||
discard
|
|
||||||
sleep 14
|
|
||||||
|
|
||||||
proc main() =
|
|
||||||
init()
|
|
||||||
mainLoop()
|
|
||||||
discard XDestroyWindow(display, window)
|
|
||||||
discard XCloseDisplay(display)
|
|
||||||
|
|
||||||
main()
|
|
Loading…
Reference in a new issue