Created base template for ImGUI application.
This commit is contained in:
@@ -1,59 +1,65 @@
|
||||
[Window][CQ]
|
||||
Size=2868,1695
|
||||
[Window][Conquest]
|
||||
Pos=0,0
|
||||
Size=1908,999
|
||||
Collapsed=0
|
||||
|
||||
[Window][Dear ImGui Demo]
|
||||
Pos=0,30
|
||||
Size=2868,1665
|
||||
Pos=0,518
|
||||
Size=954,481
|
||||
Collapsed=0
|
||||
DockId=0x00000003,0
|
||||
DockId=0x00000006,0
|
||||
|
||||
[Window][Debug##Default]
|
||||
Pos=60,60
|
||||
Size=400,400
|
||||
Collapsed=0
|
||||
|
||||
[Window][Conquest]
|
||||
Pos=0,0
|
||||
Size=2868,1695
|
||||
[Window][Example: Documents]
|
||||
Pos=0,33
|
||||
Size=1050,966
|
||||
Collapsed=0
|
||||
DockId=0x00000005,0
|
||||
|
||||
[Window][Dear ImGui Style Editor]
|
||||
Pos=123,79
|
||||
Size=1080,1629
|
||||
Collapsed=0
|
||||
|
||||
[Window][Example: Console]
|
||||
Pos=0,458
|
||||
Size=2868,1237
|
||||
Collapsed=0
|
||||
DockId=0x00000002,0
|
||||
|
||||
[Window][Example: Log]
|
||||
Pos=1951,30
|
||||
Size=917,1103
|
||||
Pos=1346,33
|
||||
Size=562,966
|
||||
Collapsed=0
|
||||
DockId=0x00000004,0
|
||||
|
||||
[Window][DockSpace Demo]
|
||||
Pos=0,0
|
||||
Size=2868,1695
|
||||
[Window][Example: Assets Browser]
|
||||
Pos=60,60
|
||||
Size=800,480
|
||||
Collapsed=0
|
||||
|
||||
[Table][0x951FCC8A,6]
|
||||
RefScale=24
|
||||
Column 0 Width=50 Sort=0v
|
||||
Column 1 Width=74
|
||||
Column 2 Width=111
|
||||
Column 3 Width=118
|
||||
Column 4 Weight=1.0000
|
||||
Column 5 Width=-1
|
||||
[Window][Example: Long text display]
|
||||
Pos=60,60
|
||||
Size=520,600
|
||||
Collapsed=0
|
||||
|
||||
[Window][Dear ImGui Demo/ResizableChild_478B81A3]
|
||||
IsChild=1
|
||||
Size=1857,115
|
||||
|
||||
[Window][Dear ImGui Demo/Red_BEEF922B]
|
||||
IsChild=1
|
||||
Size=200,100
|
||||
|
||||
[Window][Info Window]
|
||||
Pos=956,33
|
||||
Size=952,966
|
||||
Collapsed=0
|
||||
DockId=0x00000002,0
|
||||
|
||||
[Table][0xB6880529,2]
|
||||
RefScale=27
|
||||
Column 0 Sort=0v
|
||||
|
||||
[Docking][Data]
|
||||
DockSpace ID=0x3674675E Window=0x538FB738 Pos=0,30 Size=2868,1665 Split=Y Selected=0x5E5F7166
|
||||
DockNode ID=0x00000001 Parent=0x3674675E SizeRef=2868,426 Split=X Selected=0x5E5F7166
|
||||
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=1949,833 CentralNode=1 Selected=0x5E5F7166
|
||||
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=917,833 Selected=0x38CCB771
|
||||
DockNode ID=0x00000002 Parent=0x3674675E SizeRef=2868,1237 Selected=0x1BCA3180
|
||||
DockSpace ID=0xC0DFADC4 Window=0xD0388BC8 Pos=0,30 Size=2868,1665 CentralNode=1
|
||||
DockSpace ID=0x3674675E Window=0x538FB738 Pos=0,33 Size=1908,966 Split=X Selected=0x5E5F7166
|
||||
DockNode ID=0x00000003 Parent=0x3674675E SizeRef=0,0 Split=X Selected=0x5E5F7166
|
||||
DockNode ID=0x00000001 Parent=0x00000003 SizeRef=954,966 Split=Y Selected=0x5E5F7166
|
||||
DockNode ID=0x00000005 Parent=0x00000001 SizeRef=954,483 CentralNode=1
|
||||
DockNode ID=0x00000006 Parent=0x00000001 SizeRef=954,481 Selected=0x5E5F7166
|
||||
DockNode ID=0x00000002 Parent=0x00000003 SizeRef=952,966 Selected=0x7DB93FD0
|
||||
DockNode ID=0x00000004 Parent=0x3674675E SizeRef=562,966 Selected=0x3EEA4247
|
||||
|
||||
|
||||
@@ -1,112 +1,78 @@
|
||||
import nimgl/[opengl, glfw]
|
||||
import imguin/glfw_opengl
|
||||
import ./utils/[lib, windowInit]
|
||||
import ./utils/appImGui
|
||||
|
||||
proc main(hWin: glfw.GLFWWindow) =
|
||||
var
|
||||
clearColor: CColor
|
||||
showWindowDelay = 1
|
||||
showMainWindow = true
|
||||
windowClass = ImGuiWindowClass_ImGuiWindowClass()
|
||||
opt_fullscreen: bool = true
|
||||
opt_padding: bool = false
|
||||
dockspaceFlags: ImGuiDockNodeFlags = ImGuiDockNodeFlags_None.int32
|
||||
windowFlags: ImGuiWindow_Flags = ImGuiWindowFlags_MenuBar.int32 or ImGuiWindowFlags_NoDocking.int32
|
||||
proc main() =
|
||||
var app = createApp(1024, 800, imnodes = true, title = "Conquest", docking = true)
|
||||
defer: app.destroyApp()
|
||||
|
||||
# Setup background and theme colors (Background is only seen when opt_padding = true)
|
||||
clearColor = CColor(elm:(x:0.0f, y:0.0f, z:0.0f, w:0.0f))
|
||||
igStyleColorsClassic(nil)
|
||||
|
||||
# Setup fonts
|
||||
discard setupFonts()
|
||||
var showConquest = true
|
||||
|
||||
let io = igGetIO()
|
||||
|
||||
# main loop
|
||||
while not hWin.windowShouldClose:
|
||||
glfwPollEvents()
|
||||
while not app.handle.windowShouldClose:
|
||||
pollEvents()
|
||||
|
||||
if getWindowAttrib(hWin, GLFW_ICONIFIED) != 0:
|
||||
ImGui_ImplGlfw_Sleep(10)
|
||||
continue
|
||||
if app.isIconifySleep():
|
||||
continue
|
||||
newFrame()
|
||||
|
||||
# Start ImGUI frame
|
||||
ImGui_ImplOpenGL3_NewFrame()
|
||||
ImGui_ImplGlfw_NewFrame()
|
||||
igNewFrame()
|
||||
|
||||
# Create Dockspace where all windows are placed in
|
||||
if opt_fullscreen:
|
||||
# Create fullscreen dockspace as the base where all other windows are placed in
|
||||
block:
|
||||
var
|
||||
windowClass = ImGuiWindowClass_ImGuiWindowClass()
|
||||
dockspaceFlags: ImGuiDockNodeFlags = ImGuiDockNodeFlags_None.int32
|
||||
windowFlags: ImGuiWindow_Flags = ImGuiWindowFlags_MenuBar.int32 or ImGuiWindowFlags_NoDocking.int32
|
||||
|
||||
var vp = igGetMainViewport()
|
||||
igSetNextWindowPos(vp.WorkPos, ImGui_Cond_None.int32, vec2(0.0f, 0.0f))
|
||||
igSetNextWindowSize(vp.WorkSize, 0)
|
||||
igSetNextWindowViewport(vp.ID)
|
||||
igPushStyleVar_Float(ImGuiStyleVar_WindowRounding.int32, 0.0f)
|
||||
igPushStyleVar_Float(ImGuiStyleVar_WindowBorderSize.int32, 0.0f)
|
||||
windowFlags = windowFlags or (
|
||||
ImGuiWindowFlags_NoTitleBar.int32 or
|
||||
ImGuiWindowFlags_NoCollapse.int32 or
|
||||
ImGuiWindowFlags_NoResize.int32 or
|
||||
ImGuiWindowFlags_NoMove.int32 or
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus.int32 or
|
||||
ImGuiWindowFlags_NoNavFocus.int32
|
||||
)
|
||||
|
||||
windowFlags = windowFlags or ImGuiWindowFlags_NoTitleBar.int32 or ImGuiWindowFlags_NoCollapse.int32 or ImGuiWindowFlags_NoResize.int32 or ImGuiWindowFlags_NoMove.int32
|
||||
windowFlags = windowFlags or ImGuiWindowFlags_NoBringToFrontOnFocus.int32 or ImGuiWindowFlags_NoNavFocus.int32
|
||||
|
||||
else:
|
||||
dockspaceFlags = cast[ImGuiDockNodeFlags](dockspaceFlags and not ImGuiDockNodeFlags_PassthruCentralNode.int32)
|
||||
|
||||
if (dockspaceFlags and ImGuiDockNodeFlags_PassthruCentralNode.int32) == ImGuiDockNodeFlags_None.int32:
|
||||
windowFlags = cast[ImGuiWindow_Flags](windowFlags or ImGuiWindowFlags_NoBackground.int32)
|
||||
|
||||
if not opt_padding:
|
||||
# Add padding
|
||||
igPushStyleVar_Vec2(ImGuiStyleVar_WindowPadding.int32, vec2(0.0f, 0.0f))
|
||||
|
||||
igBegin("Conquest", addr showMainWindow, windowFlags)
|
||||
igBegin("Conquest", addr showConquest, windowFlags)
|
||||
defer: igEnd()
|
||||
|
||||
if not opt_padding:
|
||||
igPopStyleVar(1)
|
||||
igPopStyleVar(3)
|
||||
|
||||
if opt_fullscreen:
|
||||
igPopStyleVar(2)
|
||||
|
||||
# Create dockspace
|
||||
if (io.ConfigFlags and ImGui_ConfigFlags_DockingEnable.int32) != ImGui_ConfigFlags_None.int32:
|
||||
# Create dockspace
|
||||
igDockSpace(igGetID_Str("Conquest-Dockspace"), vec2(0.0f, 0.0f), dockspaceFlags, windowClass)
|
||||
|
||||
# Create Dockspace menu bar
|
||||
if igBeginMenuBar():
|
||||
if igBeginMenu("Options", true):
|
||||
# Create Dockspace menu bar
|
||||
if igBeginMenuBar():
|
||||
if igBeginMenu("Options", true):
|
||||
|
||||
igMenuItem("Fullscreen", nil, addr opt_fullscreen, true)
|
||||
igMenuItem("Padding", nil, addr opt_padding, true)
|
||||
if igMenuItem("Exit", nil, false, (addr showConquest) != nil):
|
||||
showConquest = false
|
||||
igEndMenu()
|
||||
igEndMenuBar()
|
||||
|
||||
if igMenuItem("Close", nil, false, (addr showMainWindow) != nil):
|
||||
showMainWindow = false
|
||||
igEndMenu()
|
||||
igEndMenuBar()
|
||||
|
||||
# Components and widgets
|
||||
igShowDemoWindow(nil)
|
||||
|
||||
|
||||
|
||||
block:
|
||||
igBegin("Info Window", nil, 0)
|
||||
defer: igEnd()
|
||||
|
||||
igEnd()
|
||||
igText(cstring(ICON_FA_USER_SHIELD & " " & getFrontendVersionString()))
|
||||
|
||||
# render
|
||||
igRender()
|
||||
glClearColor(clearColor.elm.x, clearColor.elm.y, clearColor.elm.z, clearColor.elm.w)
|
||||
glClear(GL_COLOR_BUFFER_BIT)
|
||||
ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData())
|
||||
app.render()
|
||||
|
||||
if 0 != (io.ConfigFlags and ImGui_ConfigFlags_ViewportsEnable.int32):
|
||||
var backup_current_window = glfwGetCurrentContext()
|
||||
igUpdatePlatformWindows()
|
||||
igRenderPlatformWindowsDefault(nil, nil)
|
||||
backup_current_window.makeContextCurrent()
|
||||
|
||||
hWin.swapBuffers()
|
||||
|
||||
if showWindowDelay > 0:
|
||||
dec showWindowDelay
|
||||
else:
|
||||
once: # Avoid flickering screen at startup.
|
||||
hWin.showWindow()
|
||||
if not showConquest:
|
||||
app.handle.setWindowShouldClose(true)
|
||||
|
||||
when isMainModule:
|
||||
windowInit(main)
|
||||
main()
|
||||
|
||||
BIN
src/client/resources/icon.png
Normal file
BIN
src/client/resources/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
246
src/client/utils/appImGui.nim
Normal file
246
src/client/utils/appImGui.nim
Normal file
@@ -0,0 +1,246 @@
|
||||
import os, strutils, strformat
|
||||
import nimgl/[opengl, glfw]
|
||||
export opengl, glfw
|
||||
|
||||
import imguin/[cimgui, glfw_opengl, simple]
|
||||
export cimgui, glfw_opengl, simple
|
||||
|
||||
import ./globals
|
||||
import ./opengl/[zoomglass, loadImage]
|
||||
export zoomglass, loadImage
|
||||
import ./[saveImage, setupFonts, utils, vecs]
|
||||
export saveImage, setupFonts, utils, vecs
|
||||
|
||||
proc glfwGetPlatform*(): int32 {.importc: "glfwGetPlatform".} # GLFW 3.4 >=
|
||||
|
||||
type
|
||||
IniData = object
|
||||
clearColor*: ccolor
|
||||
startupPosX*, startupPosY*: cint
|
||||
viewportWidth*, viewportHeight*: cint
|
||||
imageSaveFormatIndex*: int
|
||||
theme: Theme
|
||||
|
||||
Window* = object
|
||||
handle*: glfw.GLFWwindow
|
||||
context*: ptr ImGuiContext
|
||||
imnodes*: bool
|
||||
implot*: bool
|
||||
implot3d*: bool
|
||||
implotContext: ptr ImPlotContext
|
||||
implot3dContext: ptr ImPlot3dContext
|
||||
showWindowDelay: int
|
||||
ini*: IniData
|
||||
|
||||
# Forward definitions
|
||||
proc setTheme*(this: var Window, theme: Theme): string
|
||||
|
||||
# Sections
|
||||
const
|
||||
scWindow = "Window"
|
||||
startupPosX = "startupPosX"
|
||||
startupPosY = "startupPosY"
|
||||
viewportWidth = "viewportWidth"
|
||||
viewportHeight = "viewportHeigth"
|
||||
colBGx = "colBGx"
|
||||
colBGy = "colBGy"
|
||||
colBGz = "colBGz"
|
||||
colBGw = "colBGw"
|
||||
theme = "theme"
|
||||
scImage = "Image"
|
||||
imageSaveFormatIndex = "imageSaveFormatIndex"
|
||||
|
||||
# Main setup function
|
||||
proc createApp*(w: cint = 1024, h: cint = 900, imnodes: bool = false, implot: bool = false, implot3d = false, title: string = "ImGui window", docking: bool = true): Window =
|
||||
doAssert glfwInit()
|
||||
# result.loadIni()
|
||||
result.ini.viewportWidth = w
|
||||
result.ini.viewportHeight = h
|
||||
result.implot = implot
|
||||
result.implot3d = implot3d
|
||||
result.imnodes = imnodes
|
||||
|
||||
if result.implot3d:
|
||||
result.implot = true
|
||||
|
||||
var
|
||||
fDocking = docking
|
||||
fViewport = false
|
||||
transparentViewport = false
|
||||
|
||||
block:
|
||||
if transparentViewport:
|
||||
fViewport = true
|
||||
if fViewport:
|
||||
fDocking = true
|
||||
|
||||
var glfwWin: GLFWwindow
|
||||
var glsl_version: string
|
||||
|
||||
when defined(windows):
|
||||
const versions = [[4, 4], [4, 3], [4, 2], [4, 1], [4, 0], [3, 3]]
|
||||
else:
|
||||
const versions = [[3, 3]]
|
||||
|
||||
for ver in versions:
|
||||
let
|
||||
major = ver[0].int32
|
||||
minor = ver[1].int32
|
||||
if transparentViewport:
|
||||
glfwWindowHint(GLFWVisible, GLFW_FALSE)
|
||||
|
||||
glfwWindowHint(GLFWContextVersionMajor, major)
|
||||
glfwWindowHint(GLFWContextVersionMinor, minor)
|
||||
glfwWindowHint(GLFWOpenglForwardCompat, GLFW_TRUE)
|
||||
glfwWindowHint(GLFWOpenglProfile, GLFW_OPENGL_CORE_PROFILE)
|
||||
glfwWindowHint(GLFWResizable, GLFW_TRUE)
|
||||
glfwWindowHint(GLFWVisible, GLFW_FALSE)
|
||||
glfwWindowHint(GLFWMaximized, GLFW_TRUE)
|
||||
|
||||
glfwWin = glfwCreateWindow(result.ini.viewportWidth, result.ini.viewportHeight, title = title)
|
||||
glsl_version = fmt"#version {major * 100 + minor * 10}"
|
||||
|
||||
if not glfwWin.isNil:
|
||||
break
|
||||
|
||||
if glfwWin.isNil:
|
||||
quit(-1)
|
||||
|
||||
glfwWin.makeContextCurrent()
|
||||
setWindowPos(glfwWin, result.ini.startupPosX, result.ini.startupPosY)
|
||||
glfwSwapInterval(1) # Enable vsync
|
||||
|
||||
# Load title bar icon
|
||||
var iconName = os.joinPath(fmt"{CONQUEST_ROOT}/src/client/resources/icon.png")
|
||||
LoadTileBarIcon(glfwWin, iconName)
|
||||
|
||||
doAssert glInit() # OpenGL init
|
||||
|
||||
# Setup ImGui
|
||||
result.context = igCreateContext(nil)
|
||||
|
||||
if result.imnodes: # setup ImNodes
|
||||
when defined(ImNodesEnable):
|
||||
imnodes_CreateContext()
|
||||
|
||||
if result.implot: # setup ImPlot
|
||||
when defined(ImPlotEnable) or defined(ImPlot) or defined(ImPlot3DEnable) or defined(ImPlot3D):
|
||||
result.imPlotContext = ImPlot_CreateContext()
|
||||
else:
|
||||
echo "Fatal Error!: setup ImPlot: Specify option -d:ImPlot"
|
||||
quit 1
|
||||
|
||||
if result.implot3d: # setup ImPlot3D
|
||||
when defined(ImPlot3DEnable) or defined(ImPlot3D):
|
||||
result.imPlot3dContext = ImPlot3d_CreateContext()
|
||||
else:
|
||||
echo "Fatal Error!: setup ImPlot3D: Specify option -d:ImPlot3DEnable"
|
||||
quit 1
|
||||
|
||||
if fDocking:
|
||||
var pio = igGetIO()
|
||||
pio.ConfigFlags = pio.ConfigFlags or ImGui_ConfigFlags_DockingEnable.cint
|
||||
if fViewport:
|
||||
pio.ConfigFlags = pio.ConfigFlags or ImGui_ConfigFlags_ViewportsEnable.cint
|
||||
pio.ConfigViewports_NoAutomerge = true
|
||||
|
||||
# GLFW + OpenGL
|
||||
doAssert ImGui_ImplGlfw_InitForOpenGL(cast[ptr GLFWwindow](glfwwin), true)
|
||||
doAssert ImGui_ImplOpenGL3_Init(glsl_version.cstring)
|
||||
|
||||
if transparentViewport:
|
||||
result.ini.clearColor = ccolor(elm:(x:0f, y:0f, z:0f, w:0.0f)) # Transparent
|
||||
result.handle = glfwWin
|
||||
|
||||
var pio = igGetIO()
|
||||
pio.IniFileName = fmt"{CONQUEST_ROOT}/data/layout.ini"
|
||||
setTheme(Dark)
|
||||
discard setupFonts()
|
||||
result.showWindowDelay = 2
|
||||
|
||||
# pollEvents
|
||||
proc pollEvents*() =
|
||||
glfwPollEvents()
|
||||
|
||||
# isIconifySleep
|
||||
proc isIconifySleep*(win: Window): bool =
|
||||
if getWindowAttrib(win.handle, GLFW_ICONIFIED) != 0:
|
||||
ImGui_ImplGlfw_Sleep(10)
|
||||
return true
|
||||
|
||||
# render
|
||||
proc render*(window: var Window) =
|
||||
igRender()
|
||||
glClearColor(window.ini.clearColor.elm.x, window.ini.clearColor.elm.y, window.ini.clearColor.elm.z, window.ini.clearColor.elm.w)
|
||||
glClear(GL_COLOR_BUFFER_BIT)
|
||||
ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData())
|
||||
|
||||
var pio = igGetIO()
|
||||
if 0 != (pio.ConfigFlags and ImGui_ConfigFlags_ViewportsEnable.cint):
|
||||
var backup_current_window = glfwGetCurrentContext()
|
||||
igUpdatePlatformWindows()
|
||||
igRenderPlatformWindowsDefault(nil, nil)
|
||||
backup_current_window.makeContextCurrent()
|
||||
|
||||
window.handle.swapBuffers()
|
||||
|
||||
if window.showWindowDelay > 0:
|
||||
dec window.showWindowDelay
|
||||
else:
|
||||
once: # Avoid flickering screen at startup.
|
||||
window.handle.showWindow()
|
||||
|
||||
# Cleanup
|
||||
proc destroyApp*(window: var Window) =
|
||||
# window.saveIni()
|
||||
ImGui_ImplOpenGL3_Shutdown()
|
||||
ImGui_ImplGlfw_Shutdown()
|
||||
|
||||
when defined(ImPlotEnable) or defined(ImPlot):
|
||||
if window.implot:
|
||||
window.imPlotContext.ImPlotDestroyContext()
|
||||
|
||||
when defined(ImPlot3DEnable) or defined(ImPlot3D):
|
||||
if window.implot3d:
|
||||
window.implot3dContext.ImPlot3dDestroyContext()
|
||||
|
||||
when defined(ImNodesEnable):
|
||||
if window.imnodes:
|
||||
imnodes_DestroyContext(nil)
|
||||
|
||||
window.context.igDestroyContext()
|
||||
window.handle.destroyWindow()
|
||||
glfwTerminate()
|
||||
|
||||
# newFrame
|
||||
proc newFrame*() =
|
||||
ImGui_ImplOpenGL3_NewFrame()
|
||||
ImGui_ImplGlfw_NewFrame()
|
||||
igNewFrame()
|
||||
|
||||
proc getFrontendVersionString*(): string =
|
||||
fmt"GLFW v{$glfwGetVersionString()}"
|
||||
|
||||
proc getBackendVersionString*(): string =
|
||||
fmt"OpenGL v{($cast[cstring](glGetString(GL_VERSION))).split[0]} (Backend)"
|
||||
|
||||
# setClearColor
|
||||
proc setClearColor*(win: var Window, col: ccolor) =
|
||||
win.ini.clearColor = col
|
||||
|
||||
# free
|
||||
proc free*(mem: pointer) {.importc, header:"<stdlib.h>".}
|
||||
|
||||
# setTheme
|
||||
proc setTheme*(this: var Window, theme: Theme): string =
|
||||
this.ini.theme = theme
|
||||
utils.setTheme(theme)
|
||||
return $theme
|
||||
|
||||
# getTheme
|
||||
proc getTheme*(this: Window): Theme =
|
||||
return this.ini.theme
|
||||
|
||||
# getThemeLabel
|
||||
proc getThemeLabel*(this: Window): string =
|
||||
return $this.ini.theme
|
||||
1401
src/client/utils/fonticon/IconsFontAwesome6.h
Normal file
1401
src/client/utils/fonticon/IconsFontAwesome6.h
Normal file
File diff suppressed because it is too large
Load Diff
1400
src/client/utils/fonticon/IconsFontAwesome6.nim
Normal file
1400
src/client/utils/fonticon/IconsFontAwesome6.nim
Normal file
File diff suppressed because it is too large
Load Diff
8
src/client/utils/fonticon/README.md
Normal file
8
src/client/utils/fonticon/README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
### README about C language header file
|
||||
|
||||
`IconsFontAwesome6.h` file is part of below project,
|
||||
|
||||
[https://github.com/juliettef/IconFontCppHeaders](https://github.com/juliettef/IconFontCppHeaders)
|
||||
|
||||
|
||||
by audin, 2023/04
|
||||
165
src/client/utils/fonticon/fa6/LICENSE.txt
Normal file
165
src/client/utils/fonticon/fa6/LICENSE.txt
Normal file
@@ -0,0 +1,165 @@
|
||||
Fonticons, Inc. (https://fontawesome.com)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Font Awesome Free License
|
||||
|
||||
Font Awesome Free is free, open source, and GPL friendly. You can use it for
|
||||
commercial projects, open source projects, or really almost whatever you want.
|
||||
Full Font Awesome Free license: https://fontawesome.com/license/free.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/)
|
||||
|
||||
The Font Awesome Free download is licensed under a Creative Commons
|
||||
Attribution 4.0 International License and applies to all icons packaged
|
||||
as SVG and JS file types.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
# Fonts: SIL OFL 1.1 License
|
||||
|
||||
In the Font Awesome Free download, the SIL OFL license applies to all icons
|
||||
packaged as web and desktop font files.
|
||||
|
||||
Copyright (c) 2023 Fonticons, Inc. (https://fontawesome.com)
|
||||
with Reserved Font Name: "Font Awesome".
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
SIL OPEN FONT LICENSE
|
||||
Version 1.1 - 26 February 2007
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting — in part or in whole — any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
# Code: MIT License (https://opensource.org/licenses/MIT)
|
||||
|
||||
In the Font Awesome Free download, the MIT license applies to all non-font and
|
||||
non-icon files.
|
||||
|
||||
Copyright 2023 Fonticons, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
# Attribution
|
||||
|
||||
Attribution is required by MIT, SIL OFL, and CC BY licenses. Downloaded Font
|
||||
Awesome Free files already contain embedded comments with sufficient
|
||||
attribution, so you shouldn't need to do anything additional when using these
|
||||
files normally.
|
||||
|
||||
We've kept attribution comments terse, so we ask that you do not actively work
|
||||
to remove them from files, especially code. They're a great way for folks to
|
||||
learn about Font Awesome.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
# Brand Icons
|
||||
|
||||
All brand icons are trademarks of their respective owners. The use of these
|
||||
trademarks does not indicate endorsement of the trademark holder by Font
|
||||
Awesome, nor vice versa. **Please do not use brand logos for any purpose except
|
||||
to represent the company, product, or service to which they refer.**
|
||||
10
src/client/utils/fonticon/fa6/README.md
Normal file
10
src/client/utils/fonticon/fa6/README.md
Normal file
@@ -0,0 +1,10 @@
|
||||
### README about font file
|
||||
|
||||
The `fa-solid-900.ttf` file is part of **fontawesome-free-6.4.0-web.zip**.
|
||||
|
||||
Please refer to its License file, `LICENSE.txt`
|
||||
|
||||
Web page is [https://fontawesome.com/](https://fontawesome.com/).
|
||||
|
||||
|
||||
by audin, 2023/04
|
||||
BIN
src/client/utils/fonticon/fa6/fa-solid-900.ttf
Normal file
BIN
src/client/utils/fonticon/fa6/fa-solid-900.ttf
Normal file
Binary file not shown.
1
src/client/utils/globals.nim
Normal file
1
src/client/utils/globals.nim
Normal file
@@ -0,0 +1 @@
|
||||
const CONQUEST_ROOT* {.strdefine.} = ""
|
||||
@@ -1,97 +0,0 @@
|
||||
import imguin/cimgui
|
||||
|
||||
type
|
||||
Vec2* = ImVec2
|
||||
Vec4* = ImVec4
|
||||
|
||||
proc vec2*(x, y: auto): ImVec2 =
|
||||
ImVec2(x: x.cfloat, y: y.cfloat)
|
||||
|
||||
proc vec4*(x, y, z, w: auto): ImVec4 =
|
||||
ImVec4(x: x.cfloat , y: y.cfloat , z: z.cfloat , w: w.cfloat)
|
||||
|
||||
# Tooltips
|
||||
proc setTooltip*(str:string, delay=Imgui_HoveredFlags_DelayNormal.cint, color=ImVec4(x: 1.0, y: 1.0, z: 1.0, w: 1.0)) =
|
||||
if igIsItemHovered(delay):
|
||||
if igBeginTooltip():
|
||||
igPushStyleColorVec4(ImGuiCol_Text.cint, color)
|
||||
igText(str)
|
||||
igPopStyleColor(1)
|
||||
igEndTooltip()
|
||||
|
||||
# IM_COL32
|
||||
proc IM_COL32*(a,b,c,d:uint32): ImU32 =
|
||||
return igGetColorU32_Vec4(vec4(a.cfloat/255, b.cfloat/255, c.cfloat/255, d.cfloat/255))
|
||||
|
||||
# Definitions from imguin/simple (https://github.com/dinau/imguin/blob/main/src/imguin/simple.nim)
|
||||
{.push discardable.} # Push discardable applies the {.discardable.} pragma to all functions until the {.pop.} pragma is reached
|
||||
when false:
|
||||
type CColor* = object
|
||||
x,y,z,w: cfloat
|
||||
|
||||
proc array3(self:ccolor): array[3,cfloat] =
|
||||
result = cast[array[3,cfloat]]([self.x,self.y,self.z])
|
||||
|
||||
proc newCColor(col:ImVec4):ccolor =
|
||||
result.x = col.x
|
||||
result.y = col.y
|
||||
result.z = col.z
|
||||
result.w = col.w
|
||||
|
||||
proc vec4*(self:ccolor): ImVec4 =
|
||||
ImVec4(x:self.x,y:self.y,z:self.z,w:self.z)
|
||||
|
||||
else:
|
||||
type CColor* {.union.} = object
|
||||
elm*: tuple[x,y,z,w: cfloat]
|
||||
array3*: array[3, cfloat]
|
||||
vec4*: ImVec4
|
||||
|
||||
proc igInputTextWithHint*(label: string, hint: string, buf: string, bufsize: int = buf.len, flags:Imguiinputtextflags = 0.Imguiinputtextflags, callback: ImguiInputTextCallback = nil, userdata: pointer = nil): bool {.inline,discardable.} =
|
||||
igInputTextWithHint(label.cstring, hint.cstring, buf.cstring, bufsize.cuint, flags, callback, userdata)
|
||||
|
||||
proc igPlotLines*[T](label:string, arry: openArray[T], size:int= arry.len, offset:int = 0, overlayText:string = "", smin:float = igGetFLTMax(), smax:float = igGetFLTMax(), graphSize:Imvec2 = ImVec2(x:0,y:0), stride:int = sizeof(cfloat)) {.inline.} =
|
||||
igPlotLinesFloatPtr(label.cstring, cast[ptr T](addr arry), size.cint, offset.cint, overlayText.cstring, smin.cfloat, smax.cfloat, graphSize, stride.cint)
|
||||
|
||||
when defined(ImKnobsEnable) or defined(ImKnobs):
|
||||
proc IgKnobEx*(label: cstring; p_value: ptr cfloat; v_min: cfloat; v_max: cfloat; speed: cfloat; format: cstring; variant: IgKnobVariant; size: cfloat; flags: IgKnobFlags; steps: cint; angle_min: cfloat; angle_max: cfloat): bool =
|
||||
return IgKnobFloat(label, p_value, v_min, v_max, speed, format, variant, size, flags, steps, angle_min, angle_max)
|
||||
|
||||
proc IgKnob*(label: cstring; p_value: ptr cfloat; v_min: cfloat; v_max: cfloat): bool =
|
||||
return IgKnobFloat(label, p_value, v_min, v_max, 0, "%.3f", IgKnobVariant_Tick.IgKnobVariant,0, cast[IgKnobFlags](0),10,-1,-1)
|
||||
|
||||
proc igPushStyleColor*(idx: ImGuiCol; col: ImU32) = igPushStyleColor_U32(idx, col)
|
||||
proc igPushStyleColor*(idx: ImGuiCol; col: ImVec4) = igPushStyleColor_Vec4(idx, col)
|
||||
proc igSameLine*() = igSameLine(0.0, -1.0)
|
||||
|
||||
proc igBeginMenuEx*(label: cstring, icon: cstring, enabled: bool = true): bool {.importc: "igBeginMenuEx".}
|
||||
proc igMenuItem*(label: cstring, shortcut: cstring = nil, selected: bool = false, enabled: bool = true): bool {.importc: "igMenuItem_Bool".}
|
||||
proc igMenuItem*(label: cstring, shortcut: cstring, p_selected: ptr bool, enabled: bool = true): bool {.importc: "igMenuItem_BoolPtr".}
|
||||
proc igMenuItemEx*(label: cstring, icon: cstring, shortcut: cstring = nil, selected: bool = false, enabled: bool = true): bool {.importc: "igMenuItemEx".}
|
||||
|
||||
proc igBeginChild*(str_id: cstring, size: ImVec2 = ImVec2(x: 0, y: 0), border: bool = false, flags: ImGuiWindowFlags = 0.ImGuiWindowFlags): bool {.importc: "igBeginChild_Str".}
|
||||
proc igBeginChild*(id: ImGuiID, size: ImVec2 = ImVec2(x: 0, y: 0), border: bool = false, flags: ImGuiWindowFlags = 0.ImGuiWindowFlags): bool {.importc: "igBeginChild_ID".}
|
||||
|
||||
when not defined(igGetIO):
|
||||
template igGetIO*(): ptr ImGuiIO =
|
||||
igGetIO_Nil()
|
||||
|
||||
{.pop.}
|
||||
|
||||
# Fonts
|
||||
proc pointToPx*(point: float32): cfloat =
|
||||
return ((point * 96) / 72).cfloat
|
||||
|
||||
proc setupFonts*(): (bool, string, string) =
|
||||
|
||||
let io = igGetIO()
|
||||
let
|
||||
fontPath = "/usr/share/fonts/truetype/noto/NotoMono-Regular.ttf"
|
||||
fontName = "NotoMono-Regular"
|
||||
fontSize = pointToPx(18.0f)
|
||||
|
||||
# Set base font
|
||||
io.Fonts.ImFontAtlas_AddFontFromFileTTF(fontPath.cstring, fontSize, nil, nil)
|
||||
|
||||
result = (true, fontPath, fontName)
|
||||
|
||||
2
src/client/utils/loadImage.nim
Normal file
2
src/client/utils/loadImage.nim
Normal file
@@ -0,0 +1,2 @@
|
||||
import ./opengl/loadImage
|
||||
export loadImage
|
||||
149
src/client/utils/opengl/loadImage.nim
Normal file
149
src/client/utils/opengl/loadImage.nim
Normal file
@@ -0,0 +1,149 @@
|
||||
# Install packages $ nimble stb_image nimgl
|
||||
|
||||
import std/[os, strutils, strformat]
|
||||
when defined(SDL):
|
||||
import imguin/[glad/gl]
|
||||
else:
|
||||
import nimgl/[opengl,glfw]
|
||||
|
||||
import stb_image/read as stbi
|
||||
|
||||
# Refer to:
|
||||
# OpenGLでの描画内容の画像化と保存(2012-11-07)
|
||||
# https://npal-shared.hatenablog.com/entry/20121107/1352284053
|
||||
|
||||
type
|
||||
loadSaveError = object of CatchableError
|
||||
|
||||
#------------------------
|
||||
# loadTextureFromBuffer()
|
||||
#------------------------
|
||||
proc loadTextureFromBuffer*(textureID: var uint32, xs, ys, imageWidth, imageHeight:int) =
|
||||
const comp = RGBA
|
||||
if 1 > imageWidth or 1 > imageHeight :
|
||||
raise newException(loadSaveError, "Error!: Rect of image is mismatch")
|
||||
var
|
||||
texBuffer = newSeq[GLuByte](imageWidth * imageHeight * comp)
|
||||
dataBuffer = newSeq[GLuByte](imageWidth * imageHeight * comp)
|
||||
|
||||
# Specify OpenGL buffer to be read, 'GL_FRONT': Front buffer, 'GL_BACK': Back buffer
|
||||
glReadBuffer( GL_BACK )
|
||||
# Read form OpenGL buffer and save to local buffer
|
||||
glReadPixels( xs.GLint, ys.GLint, # x,y position (left down) at start //0 or getCurrentWidth() - 1
|
||||
imageWidth.GLsizei, imageHeight.GLsizei, # width, height to be read
|
||||
GL_RGBA, # Read type
|
||||
GL_UNSIGNED_BYTE, # Save type
|
||||
texBuffer[0].addr) # Pointer to pixel data
|
||||
|
||||
when true:
|
||||
# Fix upside-down of image
|
||||
let widthStep = comp * imageWidth
|
||||
var n = 0
|
||||
for y in 0..<imageHeight:
|
||||
for x in 0..<imageWidth:
|
||||
dataBuffer[ ( imageHeight - y - 1 ) * widthStep + (x * comp) + comp - 4 ] = texBuffer[n + comp - 4] # copy R
|
||||
dataBuffer[ ( imageHeight - y - 1 ) * widthStep + (x * comp) + comp - 3 ] = texBuffer[n + comp - 3] # copy G
|
||||
dataBuffer[ ( imageHeight - y - 1 ) * widthStep + (x * comp) + comp - 2 ] = texBuffer[n + comp - 2] # copy B
|
||||
dataBuffer[ ( imageHeight - y - 1 ) * widthStep + (x * comp) + comp - 1 ] = texBuffer[n + comp - 1] # copy A
|
||||
inc(n,comp)
|
||||
|
||||
# Setup filtering parameters for display
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR.GLint)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR.GLint)
|
||||
# This is required on WebGL for non power-of-two textures
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE.GLint)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE.GLint)
|
||||
|
||||
# Upload pixels into texture
|
||||
#if defined(GL_UNPACK_ROW_LENGTH) && !defined(__EMSCRIPTEN__)
|
||||
# TODO
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)
|
||||
#endif
|
||||
|
||||
# Create a OpenGL texture identifier
|
||||
var loadReq{.global.}:bool
|
||||
if textureID == 0:
|
||||
glGenTextures(1, addr textureID)
|
||||
loadReq = true
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, textureID)
|
||||
|
||||
# Load texture
|
||||
var err:int
|
||||
if loadReq:
|
||||
loadReq = false
|
||||
glTexImage2D(GL_TEXTURE_2D # target
|
||||
, 0 # level
|
||||
, GL_RGBA.GLint # internal format
|
||||
, imageWidth.GLSizei # width
|
||||
, imageHeight.GLsizei # height
|
||||
, 0 # [Border]: 0: Not have border 1: Have border
|
||||
# https://stackoverflow.com/questions/913801/what-does-border-mean-in-the-glteximage2d-function
|
||||
, GL_RGBA # format
|
||||
, GL_UNSIGNED_BYTE # type
|
||||
, dataBuffer[0].addr) # *pixels
|
||||
err = glGetError().int
|
||||
if err != 0:
|
||||
raise newException(loadSaveError, fmt"Error!: [0x{err:X}]: glTexImage2D()")
|
||||
|
||||
# Update texture
|
||||
glTexSubImage2D(GL_TEXTURE_2D # target
|
||||
, 0.GLint # level
|
||||
, 0.Glint, 0.GLint # x,y offset
|
||||
, imageWidth.GLsizei
|
||||
, imageHeight.GLsizei
|
||||
, GL_RGBA #, GL_UNSIGNED_INT_8_8_8_8_REV # is Fast than GL_UNSIGNED_BYTE ?
|
||||
, GL_UNSIGNED_BYTE
|
||||
, dataBuffer[0].addr)
|
||||
err = glGetError().int
|
||||
if err != 0:
|
||||
raise newException(loadSaveError, fmt"Error! [0x{err:X}]: glTexSubImage2D()")
|
||||
|
||||
#---------------------
|
||||
# loadTextureFromFile
|
||||
#---------------------
|
||||
proc loadTextureFromFile*(filename: string, outTexture: var GLuint, outWidth: var int, outHeight: var int): bool {.discardable.} =
|
||||
if not filename.fileExists:
|
||||
echo "Error!: Image file not found error: ", filename
|
||||
return false
|
||||
var
|
||||
channels: int
|
||||
image_data = stbi.load(filename, outWidth, outHeight, channels, stbi.RGBA)
|
||||
|
||||
# Create a OpenGL texture identifier
|
||||
glGenTextures(1, addr outTexture)
|
||||
glBindTexture(GL_TEXTURE_2D, outTexture)
|
||||
# Setup filtering parameters for display
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR.GLint)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR.GLint)
|
||||
# This is required on WebGL for non power-of-two textures
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE.GLint)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE.GLint)
|
||||
|
||||
# Upload pixels into texture
|
||||
#if defined(GL_UNPACK_ROW_LENGTH) && !defined(__EMSCRIPTEN__)
|
||||
# TODO
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)
|
||||
#endif
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA.GLint
|
||||
, outWidth.GLSizei, outHeight.GLsizei
|
||||
, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data[0].addr)
|
||||
return true
|
||||
|
||||
when not defined(SDL):
|
||||
#---------------------
|
||||
# Load title bar icon
|
||||
#---------------------
|
||||
proc LoadTileBarIcon*(window:GLFWwindow, iconName:string) =
|
||||
if iconName.fileExists:
|
||||
var
|
||||
w, h: int
|
||||
channels: int
|
||||
pixels: seq[byte]
|
||||
pixels = stbi.load(iconName, w, h, channels, stbi.RGBA)
|
||||
var img = GLFWImage(width: w.int32, height: h.int32
|
||||
, pixels: cast[ptr cuchar](pixels[0].addr))
|
||||
glfw.setWindowIcon(window, 1, img.addr)
|
||||
else:
|
||||
echo "Not found: ",iconName
|
||||
glfw.setWindowIcon(window, 0, nil)
|
||||
41
src/client/utils/opengl/zoomglass.nim
Normal file
41
src/client/utils/opengl/zoomglass.nim
Normal file
@@ -0,0 +1,41 @@
|
||||
import imguin/[cimgui,simple]
|
||||
import loadImage
|
||||
import ../fonticon/IconsFontAwesome6
|
||||
|
||||
#--------------
|
||||
#--- zoomGlass
|
||||
#--------------
|
||||
proc zoomGlass*(textureID: var uint32, itemWidth:int, itemPosTop, itemPosEnd:ImVec2 , capture = false) =
|
||||
# itemPosTop and itemPosEnd are absolute position in main window.
|
||||
if igBeginItemTooltip():
|
||||
defer: igEndTooltip()
|
||||
let itemHeight = itemPosEnd.y.int - itemPosTop.y.int
|
||||
let my_tex_w = itemWidth.float
|
||||
let my_tex_h = itemHeight.float
|
||||
let wkSize = igGetMainViewport().Worksize
|
||||
if capture:
|
||||
loadTextureFromBuffer(textureID # TextureID
|
||||
, itemPosTop.x.int # x start pos
|
||||
, wkSize.y.int - itemPosEnd.y.int # y start pos
|
||||
, itemWidth ,itemHeight) # Image width and height must be 2^n.
|
||||
#igText("lbp: (%.2f, %.2f)", pio.MousePos.x, pio.MousePos.y)
|
||||
let pio = igGetIO()
|
||||
let region_sz = 32.0f
|
||||
var region_x = pio.MousePos.x - itemPosTop.x - region_sz * 0.5f
|
||||
var region_y = pio.MousePos.y - itemPosTop.y - region_sz * 0.5f
|
||||
let zoom = 4.0f
|
||||
if region_x < 0.0f:
|
||||
region_x = 0.0f
|
||||
elif region_x > (my_tex_w - region_sz):
|
||||
region_x = my_tex_w - region_sz
|
||||
if region_y < 0.0f:
|
||||
region_y = 0.0f
|
||||
elif region_y > my_tex_h - region_sz:
|
||||
region_y = my_tex_h - region_sz
|
||||
let uv0 = ImVec2(x: (region_x) / my_tex_w, y: (region_y) / my_tex_h)
|
||||
let uv1 = ImVec2(x: (region_x + region_sz) / my_tex_w, y: (region_y + region_sz) / my_tex_h)
|
||||
let tint_col = ImVec4(x: 1.0f, y: 1.0f, z: 1.0f, w: 1.0f) #// No tint
|
||||
let border_col = ImVec4(x: 0.22f, y: 0.56f, z: 0.22f, w: 1.0f) # Green
|
||||
igText(ICON_FA_MAGNIFYING_GLASS & " 4 x")
|
||||
let texRef = ImTextureRef(internal_TexData: nil, internal_TexID: textureID)
|
||||
igImage(texRef, ImVec2(x: region_sz * zoom, y: region_sz * zoom), uv0, uv1) #, tint_col, border_col)
|
||||
58
src/client/utils/saveImage.nim
Normal file
58
src/client/utils/saveImage.nim
Normal file
@@ -0,0 +1,58 @@
|
||||
import std/[os,strutils]
|
||||
import nimgl/[opengl]
|
||||
import stb_image/write as stbiw
|
||||
|
||||
# saveImage
|
||||
proc saveImage*(fname:string, xs, ys, width, height:int, comp:int = RGB,quality:int = 90) =
|
||||
# Image size must be 2*n
|
||||
let imageWidth = (width div 2) * 2
|
||||
let imageHeight = (height div 2) * 2
|
||||
if not (comp == RGB):
|
||||
echo "Error!: Color component numbers must be 3 (RGB) at saveImage.nim"
|
||||
return
|
||||
if 1 > imageWidth or 1 > imageHeight :
|
||||
echo "Error!: Rect of save image is mismatch at saveImage.nim"
|
||||
return
|
||||
|
||||
var
|
||||
texBuffer = newSeq[GLuByte](imageWidth * imageHeight * comp)
|
||||
dataBuffer = newSeq[GLuByte](imageWidth * imageHeight * comp)
|
||||
|
||||
glReadBuffer( GL_BACK )
|
||||
glReadPixels( xs.GLint, ys.GLint,
|
||||
imageWidth.GLsizei, imageHeight.GLsizei,
|
||||
GL_RGB,
|
||||
GL_UNSIGNED_BYTE,
|
||||
texBuffer[0].addr
|
||||
)
|
||||
|
||||
# Set upside-down
|
||||
let widthStep = 3 * imageWidth
|
||||
var n = 0
|
||||
for y in 0..<imageHeight:
|
||||
for x in 0..<imageWidth:
|
||||
dataBuffer[ ( imageHeight - y - 1 ) * widthStep + (x * 3) + 0 ] = texBuffer[n + 0] # copy R
|
||||
dataBuffer[ ( imageHeight - y - 1 ) * widthStep + (x * 3) + 1 ] = texBuffer[n + 1] # copy G
|
||||
dataBuffer[ ( imageHeight - y - 1 ) * widthStep + (x * 3) + 2 ] = texBuffer[n + 2] # copy B
|
||||
inc(n,3)
|
||||
|
||||
# Save image
|
||||
var
|
||||
(_,_,ext) = fname.splitfile()
|
||||
res:bool
|
||||
case ext.toLowerAscii()
|
||||
of ".jpg",".jpeg":
|
||||
# JPEG quality is 90% default. quality=1..100
|
||||
res = stbiw.writeJPG(fname, imageWidth, imageHeight, comp, dataBuffer, quality)
|
||||
of ".png":
|
||||
res = stbiw.writePNG(fname, imageWidth, imageHeight, comp, dataBuffer)
|
||||
of ".bmp":
|
||||
res = stbiw.writeBMP(fname, imageWidth, imageHeight, comp, dataBuffer)
|
||||
of ".tga":
|
||||
# if quality == 0 then useRLE == false.
|
||||
res = stbiw.writeTGA(fname, imageWidth, imageHeight, comp, dataBuffer, useRLE = (quality > 0))
|
||||
else:
|
||||
echo "Error! Unrecognize image extension: [",ext,"]"
|
||||
res = false
|
||||
if not res:
|
||||
echo "Error!: at stbiw.writeNNN() function in saveImage.nim"
|
||||
76
src/client/utils/setupFonts.nim
Normal file
76
src/client/utils/setupFonts.nim
Normal file
@@ -0,0 +1,76 @@
|
||||
import os, strformat
|
||||
import imguin/[cimgui, simple]
|
||||
|
||||
import ./globals
|
||||
import ../utils/fonticon/IconsFontAwesome6
|
||||
export IconsFontAwesome6
|
||||
|
||||
let IconfontFullPath = fmt"{CONQUEST_ROOT}/src/client/utils/fonticon/fa6/fa-solid-900.ttf"
|
||||
|
||||
# Convert point to pixel
|
||||
proc point2px*(point: float32): cfloat = ((point * 96) / 72).cfloat
|
||||
|
||||
# setupFonts
|
||||
type
|
||||
TFontInfo = object
|
||||
fontDir, osRootDir: string
|
||||
fontTable: seq[(string, string, float)] # path, name, point
|
||||
|
||||
when defined(windows):
|
||||
const
|
||||
fontInfo = TFontInfo(
|
||||
osRootDir: os.getEnv("windir"), # get OS root
|
||||
fontDir: "fonts",
|
||||
fontTable: @[ #
|
||||
("segoeui.ttf", "Seoge UI", 14.4),
|
||||
]
|
||||
)
|
||||
else: # For Debian/Ubuntu/Mint
|
||||
const
|
||||
fontInfo = TFontInfo(
|
||||
osRootDir: "/",
|
||||
fontDir: "usr/share/fonts",
|
||||
fontTable: @[
|
||||
("truetype/noto/NotoSansMono-Regular.ttf", "Noto Sans Mono", 20.0)
|
||||
]
|
||||
)
|
||||
|
||||
proc new_ImFontConfig(): ImFontConfig =
|
||||
# Custom constructor with default params taken from imgui.h
|
||||
result.FontDataOwnedByAtlas = true
|
||||
result.FontNo = 0
|
||||
result.OversampleH = 3
|
||||
result.OversampleV = 1
|
||||
result.PixelSnapH = false
|
||||
result.GlyphMaxAdvanceX = float.high
|
||||
result.RasterizerMultiply = 1.0
|
||||
result.RasterizerDensity = 1.0
|
||||
result.MergeMode = false
|
||||
result.EllipsisChar = cast[ImWchar](-1)
|
||||
|
||||
proc setupFonts*(): (bool, string, string) =
|
||||
let pio = igGetIO()
|
||||
var config {.global.} = new_ImFontConfig()
|
||||
|
||||
# Load first base font
|
||||
result = (false, "Default", "ProggyClean.ttf")
|
||||
var seqFontNames: seq[(string, string)]
|
||||
for (fontName, fontTitle, point) in fontInfo.fontTable:
|
||||
let fontFullPath = os.joinPath(fontInfo.osRootDir, fontInfo.fontDir, fontName)
|
||||
if os.fileExists(fontFullPath):
|
||||
seqFontNames.add((fontName, fontTitle))
|
||||
pio.Fonts.ImFontAtlas_AddFontFromFileTTF(fontFullPath.cstring, point.point2px, nil, nil)
|
||||
break
|
||||
|
||||
if seqFontNames.len > 0:
|
||||
result = (true, seqFontNames[0][0].extractFilename, seqFontNames[0][1])
|
||||
else:
|
||||
pio.Fonts.ImFontAtlas_AddFontDefault(nil)
|
||||
|
||||
# Merge Icon font
|
||||
config.MergeMode = true
|
||||
var ranges_icon_fonts {.global.} = [ICON_MIN_FA.uint16, ICON_MAX_FA.uint16, 0]
|
||||
if os.fileExists(IconfontFullPath):
|
||||
pio.Fonts.ImFontAtlas_AddFontFromFileTTF(IconfontFullPath.cstring, 11.point2px, addr config, addr ranges_icon_fonts[0])
|
||||
else:
|
||||
echo "Error!: Can't find Icon fonts: ", IconfontFullPath
|
||||
45
src/client/utils/togglebutton.nim
Normal file
45
src/client/utils/togglebutton.nim
Normal file
@@ -0,0 +1,45 @@
|
||||
import imguin/cimgui
|
||||
import ../utils/[utils,vecs]
|
||||
|
||||
#--------------------------------------------------------
|
||||
# This is very simple toggle button implement from
|
||||
# https://github.com/sonoro1234/anima/blob/09901c69586bddd6d0463e8b7460eb251a1837e2/anima/igwidgets.lua#L6-L30
|
||||
# Refer to
|
||||
# https://github.com/ocornut/imgui/issues/1537
|
||||
#--------------------------------------------------------
|
||||
|
||||
# igToggleButton
|
||||
proc igToggleButton*(str_id:string, v: var bool): bool =
|
||||
var pos: ImVec2
|
||||
igGetCursorScreenPos(addr pos)
|
||||
let draw_list = igGetWindowDrawList()
|
||||
let height = igGetFrameHeight() * 0.9
|
||||
let width = height * 1.65
|
||||
let radius = height * 0.50
|
||||
|
||||
var ret = false
|
||||
if igInvisibleButton(str_id.cstring, vec2(width, height), 0.ImGuiButtonFlags):
|
||||
v = not v
|
||||
ret = true
|
||||
var col_bg, col_base: ImU32
|
||||
if igIsItemHovered(0.ImGuiHoveredFlags):
|
||||
col_base = IM_COL32(218-20, 218-20, 218-20, 255)
|
||||
col_bg = col_base
|
||||
if v:
|
||||
col_bg = col_base or igGetColorU32_U32(ImGuiCol_ButtonHovered.ImU32, 1)
|
||||
else:
|
||||
col_base = IM_COL32(218, 218, 218, 255)
|
||||
col_bg = col_base
|
||||
if v:
|
||||
col_bg = col_base or igGetColorU32_U32(ImGuiCol_Button.ImU32, 1)
|
||||
|
||||
draw_list.ImDrawList_AddRectFilled(pos, vec2(pos.x + width, pos.y + height), col_bg, height * 0.5, 0.ImDrawFlags)
|
||||
var m:cfloat
|
||||
if v:
|
||||
m = pos.x + width - radius
|
||||
else:
|
||||
m = pos.x + radius
|
||||
draw_list.ImDrawList_AddCircleFilled(vec2(m , pos.y + radius) ,radius - 1.5 ,IM_COL32(255, 255, 255, 255) ,0)
|
||||
igSameLine(0.0, -1.0)
|
||||
igText(str_id)
|
||||
return ret
|
||||
31
src/client/utils/utils.nim
Normal file
31
src/client/utils/utils.nim
Normal file
@@ -0,0 +1,31 @@
|
||||
import imguin/[cimgui]
|
||||
import ./vecs
|
||||
|
||||
#---------------
|
||||
#--- setTooltip
|
||||
#---------------
|
||||
proc setTooltip*(str:string, delay=Imgui_HoveredFlags_DelayNormal.cint, color=ImVec4(x: 1.0, y: 1.0, z: 1.0, w: 1.0)) =
|
||||
if igIsItemHovered(delay):
|
||||
if igBeginTooltip():
|
||||
igPushStyleColorVec4(ImGuiCol_Text.cint, color)
|
||||
igText(str)
|
||||
igPopStyleColor(1)
|
||||
igEndTooltip()
|
||||
|
||||
type
|
||||
Theme* = enum
|
||||
Light, Dark, Classic
|
||||
|
||||
# setTheme
|
||||
proc setTheme*(themeName: Theme) =
|
||||
case themeName
|
||||
of Light:
|
||||
igStyleColorsLight(nil)
|
||||
of Dark:
|
||||
igStyleColorsDark(nil)
|
||||
of Classic:
|
||||
igStyleColorsClassic(nil)
|
||||
|
||||
# IM_COL32
|
||||
proc IM_COL32*(a,b,c,d:uint32): ImU32 =
|
||||
return igGetColorU32_Vec4(vec4(a.cfloat/255, b.cfloat/255, c.cfloat/255, d.cfloat/255))
|
||||
11
src/client/utils/vecs.nim
Normal file
11
src/client/utils/vecs.nim
Normal file
@@ -0,0 +1,11 @@
|
||||
import imguin/cimgui
|
||||
|
||||
type
|
||||
Vec2* = ImVec2
|
||||
Vec4* = ImVec4
|
||||
|
||||
proc vec2*(x, y: auto): ImVec2 =
|
||||
ImVec2(x: x.cfloat, y: y.cfloat)
|
||||
|
||||
proc vec4*(x, y, z, w: auto): ImVec4 =
|
||||
ImVec4(x: x.cfloat , y: y.cfloat , z: z.cfloat , w: w.cfloat)
|
||||
@@ -1,62 +0,0 @@
|
||||
import os
|
||||
import nimgl/[opengl, glfw]
|
||||
import imguin/glfw_opengl
|
||||
import ./lib
|
||||
|
||||
const CONQUEST_ROOT* {.strdefine.} = ""
|
||||
|
||||
when defined(windows):
|
||||
when not defined(vcc): # imguinVcc.res TODO WIP
|
||||
include ./res/resource
|
||||
import tinydialogs
|
||||
|
||||
# Forward definitions
|
||||
proc windowInit*(winMain: proc(win: glfw.GLFWWindow)) =
|
||||
doAssert glfwInit()
|
||||
defer: glfwTerminate()
|
||||
|
||||
glfwWindowHint(GLFWContextVersionMajor, 3)
|
||||
glfwWindowHint(GLFWContextVersionMinor, 3)
|
||||
glfwWindowHint(GLFWOpenglForwardCompat, GLFW_TRUE)
|
||||
glfwWindowHint(GLFWOpenglProfile, GLFW_OPENGL_CORE_PROFILE)
|
||||
glfwWindowHint(GLFWResizable, GLFW_TRUE)
|
||||
glfwWindowHint(GLFWVisible, GLFW_FALSE)
|
||||
glfwWindowHint(GLFWMaximized, GLFW_TRUE) # Maximize Window on startup
|
||||
|
||||
var glfwWin = glfwCreateWindow(1024, 800, "Conquest")
|
||||
if glfwWin.isNil:
|
||||
quit(-1)
|
||||
|
||||
glfwWin.makeContextCurrent()
|
||||
defer: glfwWin.destroyWindow()
|
||||
|
||||
glfwSwapInterval(1) # Enable vsync
|
||||
|
||||
# TODO: Set application icon (requires imguin_examples/utils/loadImage [https://github.com/dinau/imguin_examples/blob/main/utils/opengl/loadImage.nim])
|
||||
# var IconName = joinPath(CONQUEST_ROOT, "src/client/resources/icon.png")
|
||||
# LoadTileBarIcon(glfwWin, IconName)
|
||||
|
||||
doAssert glInit() # OpenGL init
|
||||
|
||||
# Setup ImGui
|
||||
let context = igCreateContext(nil)
|
||||
defer: context.igDestroyContext()
|
||||
|
||||
# Configure docking
|
||||
var pio = igGetIO()
|
||||
pio.ConfigFlags = pio.ConfigFlags or ImGui_ConfigFlags_DockingEnable.int32
|
||||
|
||||
# GLFW + OpenGL
|
||||
const glsl_version = "#version 130" # GL 3.0 + GLSL 130
|
||||
doAssert ImGui_ImplGlfw_InitForOpenGL(cast[ptr GLFWwindow](glfwwin), true)
|
||||
defer: ImGui_ImplGlfw_Shutdown()
|
||||
doAssert ImGui_ImplOpenGL3_Init(glsl_version)
|
||||
defer: ImGui_ImplOpenGL3_Shutdown()
|
||||
|
||||
# Set ini filename
|
||||
pio.IniFileName = CONQUEST_ROOT & "/data/layout.ini"
|
||||
|
||||
glfwWin.winMain()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user