Skip to content

Commit

Permalink
Merge pull request #4 from guzba/master
Browse files Browse the repository at this point in the history
stuff
  • Loading branch information
treeform authored Oct 15, 2021
2 parents 610d8d0 + a3442d6 commit 26d268e
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 102 deletions.
12 changes: 0 additions & 12 deletions bindings/bindings.nim
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,6 @@ proc takeError(): string =
proc checkError(): bool =
result = lastError != nil

proc isVisible(window: Window): bool =
window.visible

proc show(window: Window) =
window.visible = true

proc hide(window: Window) =
window.visible = false

exportProcs:
checkError
takeError
Expand All @@ -26,9 +17,6 @@ exportRefObject Window:
constructor:
newWindow
procs:
show
hide
isVisible
makeContextCurrent
swapBuffers

Expand Down
2 changes: 1 addition & 1 deletion examples/basic.nim
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ proc display() =
window.swapBuffers()

while true:
# pollEvents()
pollEvents()
display()
26 changes: 24 additions & 2 deletions src/windy.nim
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,39 @@ proc init*() {.raises: [WindyError]} =
platformInit()

proc newWindow*(
windowTitle: string, width, height: int
title: string,
w: int,
h: int,
vsync = true,
openglMajorVersion = 4,
openglMinorVersion = 1,
msaa = msaa8x,
depthBits = 0,
stencilBits = 0
): Window {.raises: [WindyError]} =
# resizeable, fullscreen, transparent, decorated, floating
result = Window()
result.platform = newPlatformWindow(windowTitle, width, height)
result.platform = newPlatformWindow(
title,
w,
h,
vsync,
openglMajorVersion,
openglMinorVersion,
msaa,
depthBits,
stencilBits
)

proc makeContextCurrent*(window: Window) {.raises: [WindyError]} =
window.platform.makeContextCurrent()

proc swapBuffers*(window: Window) {.raises: [WindyError]} =
window.platform.swapBuffers()

proc pollEvents*() =
platformPollEvents()

proc `visible`*(window: Window): bool =
discard

Expand Down
6 changes: 5 additions & 1 deletion src/windy/common.nim
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
type WindyError* = object of ValueError
type
WindyError* = object of ValueError

MSAA* = enum
msaaDisabled = 0, msaa2x = 2, msaa4x = 4, msaa8x = 8
217 changes: 131 additions & 86 deletions src/windy/platforms/win32/platform.nim
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@ const
WGL_STENCIL_BITS_ARB = 0x2023
WGL_FULL_ACCELERATION_ARB = 0x2027
WGL_TYPE_RGBA_ARB = 0x202B
WGL_SAMPLES_ARB = 0x2042

WGL_CONTEXT_MAJOR_VERSION_ARB = 0x2091
WGL_CONTEXT_MINOR_VERSION_ARB = 0x2092
WGL_CONTEXT_PROFILE_MASK_ARB = 0x9126
WGL_CONTEXT_CORE_PROFILE_BIT_ARB = 0x00000001
# WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB = 0x00000002
WGL_CONTEXT_FLAGS_ARB = 0x2094
# WGL_CONTEXT_DEBUG_BIT_ARB = 0x0001
WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB = 0x0002

type
PlatformWindow* = ref object
Expand All @@ -26,7 +31,7 @@ type
hglrc: HGLRC

var
initialized*: bool
initialized: bool
windows*: seq[PlatformWindow]
wglCreateContext: wglCreateContext
wglDeleteContext: wglDeleteContext
Expand All @@ -36,6 +41,7 @@ var
wglMakeCurrent: wglMakeCurrent
wglCreateContextAttribsARB: wglCreateContextAttribsARB
wglChoosePixelFormatARB: wglChoosePixelFormatARB
wglSwapIntervalEXT: wglSwapIntervalEXT

proc wstr*(str: string): string =
let wlen = MultiByteToWideChar(
Expand Down Expand Up @@ -79,16 +85,16 @@ proc registerWindowClass(windowClassName: string, wndProc: WNDPROC) =
raise newException(WindyError, "Error registering window class")

proc createWindow(
windowClassName, windowTitle: string, x, y, w, h: int
windowClassName, title: string, x, y, w, h: int
): HWND =
let
windowClassName = windowClassName.wstr()
windowTitle = windowTitle.wstr()
title = title.wstr()

result = CreateWindowExW(
WS_EX_APPWINDOW,
cast[ptr WCHAR](windowClassName[0].unsafeAddr),
cast[ptr WCHAR](windowTitle[0].unsafeAddr),
cast[ptr WCHAR](title[0].unsafeAddr),
WS_OVERLAPPEDWINDOW,
x.int32,
y.int32,
Expand Down Expand Up @@ -187,6 +193,10 @@ proc loadOpenGL() =
cast[wglChoosePixelFormatARB](
wglGetProcAddress("wglChoosePixelFormatARB")
)
wglSwapIntervalEXT =
cast[wglSwapIntervalEXT](
wglGetProcAddress("wglSwapIntervalEXT")
)

discard wglMakeCurrent(hdc, 0)
discard wglDeleteContext(hglrc)
Expand All @@ -208,6 +218,29 @@ proc platformInit*() =
registerWindowClass(windowClassName, wndProc)
initialized = true

proc platformPollEvents*() =
var msg: MSG
while PeekMessageW(msg.addr, 0, 0, 0, PM_REMOVE) > 0:
if msg.message == WM_QUIT:
for window in windows:
discard wndProc(window.hwnd, WM_CLOSE, 0, 0)
# app.quitRequested = true
else:
discard TranslateMessage(msg.addr)
discard DispatchMessageW(msg.addr)

proc destroy(window: PlatformWindow) =
if window.hglrc != 0:
discard wglMakeCurrent(window.hdc, 0)
discard wglDeleteContext(window.hglrc)
window.hglrc = 0
if window.hdc != 0:
discard ReleaseDC(window.hWnd, window.hdc)
window.hdc = 0
if window.hWnd != 0:
discard DestroyWindow(window.hWnd)
window.hWnd = 0

proc show*(window: PlatformWindow) =
discard ShowWindow(window.hWnd, SW_SHOW)

Expand All @@ -222,97 +255,109 @@ proc swapBuffers*(window: PlatformWindow) =
raise newException(WindyError, "Error swapping buffers")

proc newPlatformWindow*(
windowTitle: string,
x, y, w, h: int
title: string,
w: int,
h: int,
vsync: bool,
openglMajorVersion: int,
openglMinorVersion: int,
msaa: MSAA,
depthBits: int,
stencilBits: int
): PlatformWindow =
result = PlatformWindow()
result.hWnd = createWindow(
windowClassName,
windowTitle,
x,
y,
title,
CW_USEDEFAULT,
CW_USEDEFAULT,
w,
h
)
result.hdc = getDC(result.hWnd)

const GL_TRUE = 1
let pixelFormatAttribs = [
WGL_DRAW_TO_WINDOW_ARB.int32,
GL_TRUE,
WGL_SUPPORT_OPENGL_ARB,
GL_TRUE,
WGL_DOUBLE_BUFFER_ARB,
GL_TRUE,
WGL_ACCELERATION_ARB,
WGL_FULL_ACCELERATION_ARB,
WGL_PIXEL_TYPE_ARB,
WGL_TYPE_RGBA_ARB,
WGL_COLOR_BITS_ARB,
32,
WGL_DEPTH_BITS_ARB,
24,
WGL_STENCIL_BITS_ARB,
8,
0
]

var
pixelFormat: int32
numFormats: UINT
if wglChoosePixelFormatARB(
result.hdc,
pixelFormatAttribs[0].unsafeAddr,
nil,
1,
pixelFormat.addr,
numFormats.addr
) == 0:
raise newException(WindyError, "Error choosing pixel format")

if numFormats == 0:
raise newException(WindyError, "No pixel format chosen")

var pfd: PIXELFORMATDESCRIPTOR
if DescribePixelFormat(
result.hdc,
pixelFormat,
sizeof(PIXELFORMATDESCRIPTOR).UINT,
pfd.addr
) == 0:
raise newException(WindyError, "Error describing pixel format")

if SetPixelFormat(result.hdc, pixelFormat, pfd.addr) == 0:
raise newException(WindyError, "Error setting pixel format")

let contextAttribs = [
WGL_CONTEXT_MAJOR_VERSION_ARB.int32,
4,
WGL_CONTEXT_MINOR_VERSION_ARB,
1,
WGL_CONTEXT_PROFILE_MASK_ARB,
WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
0
]

result.hglrc = wglCreateContextAttribsARB(
result.hdc,
0,
contextAttribs[0].unsafeAddr
)
if result.hglrc == 0:
raise newException(WindyError, "Error creating OpenGL context")
try:
result.hdc = getDC(result.hWnd)

let pixelFormatAttribs = [
WGL_DRAW_TO_WINDOW_ARB.int32,
1,
WGL_SUPPORT_OPENGL_ARB,
1,
WGL_DOUBLE_BUFFER_ARB,
1,
WGL_ACCELERATION_ARB,
WGL_FULL_ACCELERATION_ARB,
WGL_PIXEL_TYPE_ARB,
WGL_TYPE_RGBA_ARB,
WGL_COLOR_BITS_ARB,
32,
WGL_DEPTH_BITS_ARB,
depthBits.int32,
WGL_STENCIL_BITS_ARB,
stencilBits.int32,
WGL_SAMPLES_ARB,
msaa.int32,
0
]

var
pixelFormat: int32
numFormats: UINT
if wglChoosePixelFormatARB(
result.hdc,
pixelFormatAttribs[0].unsafeAddr,
nil,
1,
pixelFormat.addr,
numFormats.addr
) == 0:
raise newException(WindyError, "Error choosing pixel format")

if numFormats == 0:
raise newException(WindyError, "No pixel format chosen")

var pfd: PIXELFORMATDESCRIPTOR
if DescribePixelFormat(
result.hdc,
pixelFormat,
sizeof(PIXELFORMATDESCRIPTOR).UINT,
pfd.addr
) == 0:
raise newException(WindyError, "Error describing pixel format")

if SetPixelFormat(result.hdc, pixelFormat, pfd.addr) == 0:
raise newException(WindyError, "Error setting pixel format")

let contextAttribs = [
WGL_CONTEXT_MAJOR_VERSION_ARB.int32,
openglMajorVersion.int32,
WGL_CONTEXT_MINOR_VERSION_ARB,
openglMinorVersion.int32,
WGL_CONTEXT_PROFILE_MASK_ARB,
WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
WGL_CONTEXT_FLAGS_ARB,
WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
0
]

result.hglrc = wglCreateContextAttribsARB(
result.hdc,
0,
contextAttribs[0].unsafeAddr
)
if result.hglrc == 0:
raise newException(WindyError, "Error creating OpenGL context")

# The first call to ShowWindow may ignore the parameter so do an initial
# call to clear that behavior.
result.hide()
# The first call to ShowWindow may ignore the parameter so do an initial
# call to clear that behavior.
result.hide()

result.makeContextCurrent()
result.makeContextCurrent()

windows.add(result)
if wglSwapIntervalEXT(if vsync: 1 else : 0) == 0:
raise newException(WindyError, "Error setting swap interval")

proc newPlatformWindow*(
windowTitle: string,
width, height: int
): PlatformWindow =
newPlatformWindow(windowTitle, CW_USEDEFAULT, CW_USEDEFAULT, width, height)
windows.add(result)
except WindyError as e:
result.destroy()
raise e
3 changes: 3 additions & 0 deletions src/windy/platforms/win32/windefs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ type
piFormats: ptr int32,
nNumFormats: ptr UINT
): BOOL {.stdcall, raises: [].}
wglSwapIntervalEXT* = proc(interval: int32): BOOL {.stdcall, raises: [].}
PIXELFORMATDESCRIPTOR* {.pure.} = object
nSize*: WORD
nVersion*: WORD
Expand Down Expand Up @@ -263,6 +264,8 @@ proc ShowWindow*(
nCmdShow: int32
): BOOL {.importc, stdcall, dynlib: "User32".}

proc IsWindowVisible*(hWnd: HWND): BOOL {.importc, stdcall, dynlib: "User32".}

proc PeekMessageW*(
lpMsg: LPMSG,
hWnd: HWND,
Expand Down

0 comments on commit 26d268e

Please sign in to comment.