mirror of
https://github.com/ocornut/imgui.git
synced 2026-11-07 15:05:47 +01:00
feat: Add Go (cgo) bindings for Dear ImGui + example
bindings/go/: - imgui_bridge.h/.cpp: Thin C API bridge (extern C) wrapping C++ ImGui - imgui.go: Go cgo package (CreateContext, NewFrame, Begin, Button, SliderFloat, SliderInt, Checkbox, ColorEdit3, Text, Combo, etc.) - go.mod: Module definition - README.md: Full docs with usage, building, and API reference examples/example_golang/: - main.go: Null-mode example showing ImGui from Go - go.mod: Module with replace directive for local bindings - Makefile: Build/run/clean targets Go 1.26.5 verified working on this host. CGO_ENABLED=1 required (plus a C++ compiler like g++ for the bridge compilation).
This commit is contained in:
parent
42b5a2b2a2
commit
1cd495b522
90
bindings/go/README.md
Normal file
90
bindings/go/README.md
Normal file
@ -0,0 +1,90 @@
|
||||
# Go Bindings for Dear ImGui (imgui_xl)
|
||||
|
||||
This directory provides Go (cgo) bindings for Dear ImGui via a thin C API bridge.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
imgui.go → Go package (cgo wrapper)
|
||||
imgui_bridge.h → C API declarations (extern "C")
|
||||
imgui_bridge.cpp → C API implementation (wraps C++ ImGui)
|
||||
go.mod → Go module definition
|
||||
```
|
||||
|
||||
The Go package calls C functions via cgo, which in turn call the C++ ImGui API through the bridge layer.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **Go 1.21+** (with `CGO_ENABLED=1`)
|
||||
- **C++ compiler** (g++ or clang++) on PATH
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
imgui "github.com/Turtle-PB/imgui_xl/bindings/go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
imgui.CreateContext()
|
||||
defer imgui.DestroyContext()
|
||||
|
||||
imgui.StyleColorsDark()
|
||||
|
||||
imgui.NewFrame()
|
||||
visible := imgui.Begin("Hello, Go!", nil)
|
||||
if visible {
|
||||
imgui.Text("Hello from Go!")
|
||||
imgui.Text(fmt.Sprintf("FPS: %.1f", imgui.GetFramerate()))
|
||||
}
|
||||
imgui.End()
|
||||
imgui.Render()
|
||||
}
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
```bash
|
||||
# Set up the Go module (from the example directory)
|
||||
cd examples/example_golang
|
||||
go mod tidy
|
||||
|
||||
# Build (requires C++ compiler)
|
||||
CGO_ENABLED=1 go build -o imgui_go_example
|
||||
|
||||
# Run
|
||||
./imgui_go_example
|
||||
```
|
||||
|
||||
## Available Functions
|
||||
|
||||
### Core
|
||||
- `CreateContext()`, `DestroyContext()`
|
||||
- `NewFrame()`, `Render()`
|
||||
- `Version()`, `GetFramerate()`, `GetTime()`, `GetFrameCount()`
|
||||
- `GetDisplaySize()`
|
||||
|
||||
### Style
|
||||
- `StyleColorsDark()`, `StyleColorsLight()`, `StyleColorsClassic()`
|
||||
|
||||
### Windows
|
||||
- `Begin(name, &open)`, `End()`
|
||||
- `ShowDemoWindow(&open)`
|
||||
|
||||
### Widgets
|
||||
- `Text(s)`, `TextColored(r,g,b,a,s)`, `BulletText(s)`
|
||||
- `Button(label, w, h)`, `Checkbox(label, &v)`
|
||||
- `SliderFloat(label, &v, min, max)`, `SliderInt(label, &v, min, max)`
|
||||
- `ColorEdit3(label, &col)`, `InputText(label, &buf, size)`
|
||||
- `Combo(label, ¤t, items, count)`
|
||||
|
||||
### Layout
|
||||
- `SameLine(offset, spacing)`, `Separator()`, `Spacing()`, `NewLine()`
|
||||
- `PushItemWidth(w)`, `PopItemWidth()`
|
||||
|
||||
## License
|
||||
|
||||
MIT — same as Dear ImGui
|
||||
3
bindings/go/go.mod
Normal file
3
bindings/go/go.mod
Normal file
@ -0,0 +1,3 @@
|
||||
module github.com/Turtle-PB/imgui_xl/bindings/go
|
||||
|
||||
go 1.21
|
||||
245
bindings/go/imgui.go
Normal file
245
bindings/go/imgui.go
Normal file
@ -0,0 +1,245 @@
|
||||
// Package imgui provides Go bindings for Dear ImGui via cgo.
|
||||
// It uses a thin C bridge (imgui_bridge.h/.cpp) to call the C++ ImGui API.
|
||||
//
|
||||
// Requirements:
|
||||
// - C++ compiler (g++ or clang++) for building the bridge
|
||||
// - CGO_ENABLED=1
|
||||
//
|
||||
// Build:
|
||||
// CGO_ENABLED=1 go build
|
||||
//
|
||||
// Copyright (c) 2024 OwlLogics / imgui_xl
|
||||
// Licensed under MIT
|
||||
|
||||
package imgui
|
||||
|
||||
/*
|
||||
#cgo CXXFLAGS: -std=c++11 -I${SRCDIR}/../../.. -I${SRCDIR}/../../../backends
|
||||
#cgo LDFLAGS: -lstdc++ -lm
|
||||
|
||||
// Include the C bridge header
|
||||
#include "imgui_bridge.h"
|
||||
|
||||
// We need to compile the bridge .cpp via cgo's CXX support.
|
||||
// The bridge .cpp includes all of ImGui's implementation.
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Version returns the compiled ImGui version string.
|
||||
func Version() string {
|
||||
return C.GoString(C.ig_GetVersion())
|
||||
}
|
||||
|
||||
// CreateContext creates the ImGui context.
|
||||
func CreateContext() {
|
||||
C.ig_CreateContext()
|
||||
}
|
||||
|
||||
// DestroyContext destroys the current ImGui context.
|
||||
func DestroyContext() {
|
||||
C.ig_DestroyContext()
|
||||
}
|
||||
|
||||
// NewFrame starts a new ImGui frame.
|
||||
func NewFrame() {
|
||||
C.ig_NewFrame()
|
||||
}
|
||||
|
||||
// Render finalizes the frame and prepares draw data.
|
||||
func Render() {
|
||||
C.ig_Render()
|
||||
}
|
||||
|
||||
// StyleColorsDark sets the dark color scheme.
|
||||
func StyleColorsDark() {
|
||||
C.ig_StyleColorsDark()
|
||||
}
|
||||
|
||||
// StyleColorsLight sets the light color scheme.
|
||||
func StyleColorsLight() {
|
||||
C.ig_StyleColorsLight()
|
||||
}
|
||||
|
||||
// StyleColorsClassic sets the classic color scheme.
|
||||
func StyleColorsClassic() {
|
||||
C.ig_StyleColorsClassic()
|
||||
}
|
||||
|
||||
// ShowDemoWindow shows the ImGui demo window.
|
||||
func ShowDemoWindow(open *bool) {
|
||||
if open != nil {
|
||||
v := 0
|
||||
if *open {
|
||||
v = 1
|
||||
}
|
||||
C.ig_ShowDemoWindow(&v)
|
||||
*open = v != 0
|
||||
} else {
|
||||
C.ig_ShowDemoWindow(nil)
|
||||
}
|
||||
}
|
||||
|
||||
// GetFramerate returns the current FPS.
|
||||
func GetFramerate() float32 {
|
||||
return float32(C.ig_GetFramerate())
|
||||
}
|
||||
|
||||
// GetTime returns the elapsed time since initialization.
|
||||
func GetTime() float32 {
|
||||
return float32(C.ig_GetTime())
|
||||
}
|
||||
|
||||
// GetFrameCount returns the current frame count.
|
||||
func GetFrameCount() int {
|
||||
return int(C.ig_GetFrameCount())
|
||||
}
|
||||
|
||||
// GetDisplaySize returns the display width and height.
|
||||
func GetDisplaySize() (float32, float32) {
|
||||
var w, h C.float
|
||||
C.ig_GetDisplaySize(&w, &h)
|
||||
return float32(w), float32(h)
|
||||
}
|
||||
|
||||
// --- Window functions ---
|
||||
|
||||
// Begin pushes a new window to the stack.
|
||||
// Returns true if the window is visible (not collapsed).
|
||||
func Begin(name string, open *bool) bool {
|
||||
cName := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(cName))
|
||||
var pOpen *C.int
|
||||
if open != nil {
|
||||
v := 0
|
||||
if *open {
|
||||
v = 1
|
||||
}
|
||||
pOpen = &v
|
||||
defer func() { *open = v != 0 }()
|
||||
}
|
||||
return C.ig_Begin(cName, pOpen) != 0
|
||||
}
|
||||
|
||||
// End closes the current window.
|
||||
func End() {
|
||||
C.ig_End()
|
||||
}
|
||||
|
||||
// SameLine places the next widget on the same line.
|
||||
func SameLine(offset, spacing float32) {
|
||||
C.ig_SameLine(C.float(offset), C.float(spacing))
|
||||
}
|
||||
|
||||
// Separator draws a horizontal separator.
|
||||
func Separator() {
|
||||
C.ig_Separator()
|
||||
}
|
||||
|
||||
// Spacing adds vertical spacing.
|
||||
func Spacing() {
|
||||
C.ig_Spacing()
|
||||
}
|
||||
|
||||
// --- Widget functions ---
|
||||
|
||||
// Text displays a text label.
|
||||
func Text(s string) {
|
||||
cStr := C.CString(s)
|
||||
defer C.free(unsafe.Pointer(cStr))
|
||||
C.ig_Text(cStr)
|
||||
}
|
||||
|
||||
// TextColored displays colored text.
|
||||
func TextColored(r, g, b, a float32, s string) {
|
||||
cStr := C.CString(s)
|
||||
defer C.free(unsafe.Pointer(cStr))
|
||||
C.ig_TextColored(C.float(r), C.float(g), C.float(b), C.float(a), cStr)
|
||||
}
|
||||
|
||||
// Button displays a button. Returns true if clicked.
|
||||
func Button(label string, width, height float32) bool {
|
||||
cStr := C.CString(label)
|
||||
defer C.free(unsafe.Pointer(cStr))
|
||||
return C.ig_Button(cStr, C.float(width), C.float(height)) != 0
|
||||
}
|
||||
|
||||
// Checkbox displays a checkbox.
|
||||
func Checkbox(label string, v *bool) bool {
|
||||
cStr := C.CString(label)
|
||||
defer C.free(unsafe.Pointer(cStr))
|
||||
var vC C.int
|
||||
if *v {
|
||||
vC = 1
|
||||
}
|
||||
ret := C.ig_Checkbox(cStr, &vC) != 0
|
||||
*v = vC != 0
|
||||
return ret
|
||||
}
|
||||
|
||||
// SliderFloat displays a float slider.
|
||||
func SliderFloat(label string, v *float32, vMin, vMax float32) bool {
|
||||
cStr := C.CString(label)
|
||||
defer C.free(unsafe.Pointer(cStr))
|
||||
return C.ig_SliderFloat(cStr, (*C.float)(v), C.float(vMin), C.float(vMax)) != 0
|
||||
}
|
||||
|
||||
// SliderInt displays an integer slider.
|
||||
func SliderInt(label string, v *int, vMin, vMax int) bool {
|
||||
cStr := C.CString(label)
|
||||
defer C.free(unsafe.Pointer(cStr))
|
||||
return C.ig_SliderInt(cStr, (*C.int)(v), C.int(vMin), C.int(vMax)) != 0
|
||||
}
|
||||
|
||||
// ColorEdit3 displays a 3-component color editor.
|
||||
func ColorEdit3(label string, col *[3]float32) bool {
|
||||
cStr := C.CString(label)
|
||||
defer C.free(unsafe.Pointer(cStr))
|
||||
return C.ig_ColorEdit3(cStr, (*C.float)(unsafe.Pointer(col))) != 0
|
||||
}
|
||||
|
||||
// InputText displays a text input field.
|
||||
func InputText(label string, buf *string, bufSize int) bool {
|
||||
cLabel := C.CString(label)
|
||||
defer C.free(unsafe.Pointer(cLabel))
|
||||
// Allocate a C buffer
|
||||
cBuf := C.malloc(C.size_t(bufSize))
|
||||
defer C.free(cBuf)
|
||||
C.memcpy(cBuf, unsafe.Pointer(C.CString(*buf)), C.size_t(len(*buf)+1))
|
||||
ret := C.ig_InputText(cLabel, (*C.char)(cBuf), C.int(bufSize)) != 0
|
||||
*buf = C.GoString((*C.char)(cBuf))
|
||||
return ret
|
||||
}
|
||||
|
||||
// Combo displays a dropdown combo box.
|
||||
func Combo(label string, current *int, items string, itemCount int) bool {
|
||||
cLabel := C.CString(label)
|
||||
defer C.free(unsafe.Pointer(cLabel))
|
||||
cItems := C.CString(items)
|
||||
defer C.free(unsafe.Pointer(cItems))
|
||||
return C.ig_Combo(cLabel, (*C.int)(current), cItems, C.int(itemCount)) != 0
|
||||
}
|
||||
|
||||
// BulletText displays a bulleted text item.
|
||||
func BulletText(s string) {
|
||||
cStr := C.CString(s)
|
||||
defer C.free(unsafe.Pointer(cStr))
|
||||
C.ig_BulletText(cStr)
|
||||
}
|
||||
|
||||
// NewLine inserts a new line.
|
||||
func NewLine() {
|
||||
C.ig_NewLine()
|
||||
}
|
||||
|
||||
// PushItemWidth sets the width for the next widget.
|
||||
func PushItemWidth(width float32) {
|
||||
C.ig_PushItemWidth(C.float(width))
|
||||
}
|
||||
|
||||
// PopItemWidth restores the previous item width.
|
||||
func PopItemWidth() {
|
||||
C.ig_PopItemWidth()
|
||||
}
|
||||
102
bindings/go/imgui_bridge.cpp
Normal file
102
bindings/go/imgui_bridge.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
// imgui_bridge.cpp — Thin C API bridge implementation for Dear ImGui
|
||||
// Copyright (c) 2024 OwlLogics / imgui_xl
|
||||
// Licensed under MIT
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_bridge.h"
|
||||
|
||||
// Compile the full ImGui implementation here
|
||||
#define IMGUI_IMPLEMENTATION
|
||||
#include "imgui.cpp"
|
||||
#include "imgui_demo.cpp"
|
||||
#include "imgui_draw.cpp"
|
||||
#include "imgui_tables.cpp"
|
||||
#include "imgui_widgets.cpp"
|
||||
|
||||
// === Core ===
|
||||
extern "C" void ig_CreateContext(void) { ImGui::CreateContext(); }
|
||||
extern "C" void ig_DestroyContext(void) { ImGui::DestroyContext(); }
|
||||
extern "C" void* ig_GetIO(void) { return (void*)&ImGui::GetIO(); }
|
||||
extern "C" void* ig_GetStyle(void) { return (void*)&ImGui::GetStyle(); }
|
||||
extern "C" void ig_NewFrame(void) { ImGui::NewFrame(); }
|
||||
extern "C" void ig_Render(void) { ImGui::Render(); }
|
||||
extern "C" void* ig_GetDrawData(void) { return (void*)ImGui::GetDrawData(); }
|
||||
extern "C" const char* ig_GetVersion(void) { return ImGui::GetVersion(); }
|
||||
|
||||
// === Style ===
|
||||
extern "C" void ig_StyleColorsDark(void) { ImGui::StyleColorsDark(); }
|
||||
extern "C" void ig_StyleColorsLight(void) { ImGui::StyleColorsLight(); }
|
||||
extern "C" void ig_StyleColorsClassic(void) { ImGui::StyleColorsClassic(); }
|
||||
|
||||
// === Windows ===
|
||||
extern "C" int ig_Begin(const char* name, int* p_open) {
|
||||
return ImGui::Begin(name, p_open ? (bool*)p_open : nullptr) ? 1 : 0;
|
||||
}
|
||||
extern "C" void ig_End(void) { ImGui::End(); }
|
||||
extern "C" int ig_BeginChild(const char* str_id, float w, float h, int border) {
|
||||
return ImGui::BeginChild(str_id, ImVec2(w, h), border != 0) ? 1 : 0;
|
||||
}
|
||||
extern "C" void ig_EndChild(void) { ImGui::EndChild(); }
|
||||
|
||||
// === Widgets ===
|
||||
extern "C" void ig_Text(const char* fmt) { ImGui::Text("%s", fmt); }
|
||||
extern "C" void ig_TextColored(float r, float g, float b, float a, const char* fmt) {
|
||||
ImGui::TextColored(ImVec4(r, g, b, a), "%s", fmt);
|
||||
}
|
||||
extern "C" void ig_BulletText(const char* fmt) { ImGui::BulletText("%s", fmt); }
|
||||
extern "C" int ig_Button(const char* label, float w, float h) {
|
||||
return ImGui::Button(label, ImVec2(w, h)) ? 1 : 0;
|
||||
}
|
||||
extern "C" int ig_InvisibleButton(const char* str_id, float w, float h) {
|
||||
return ImGui::InvisibleButton(str_id, ImVec2(w, h)) ? 1 : 0;
|
||||
}
|
||||
extern "C" int ig_Checkbox(const char* label, int* v) {
|
||||
bool b = *v != 0;
|
||||
int ret = ImGui::Checkbox(label, &b) ? 1 : 0;
|
||||
*v = b ? 1 : 0;
|
||||
return ret;
|
||||
}
|
||||
extern "C" int ig_SliderFloat(const char* label, float* v, float v_min, float v_max) {
|
||||
return ImGui::SliderFloat(label, v, v_min, v_max) ? 1 : 0;
|
||||
}
|
||||
extern "C" int ig_SliderInt(const char* label, int* v, int v_min, int v_max) {
|
||||
return ImGui::SliderInt(label, v, v_min, v_max) ? 1 : 0;
|
||||
}
|
||||
extern "C" int ig_ColorEdit3(const char* label, float* col) {
|
||||
return ImGui::ColorEdit3(label, col) ? 1 : 0;
|
||||
}
|
||||
extern "C" int ig_ColorEdit4(const char* label, float* col, int flags) {
|
||||
return ImGui::ColorEdit4(label, col, flags) ? 1 : 0;
|
||||
}
|
||||
extern "C" int ig_InputText(const char* label, char* buf, int buf_size) {
|
||||
return ImGui::InputText(label, buf, (size_t)buf_size) ? 1 : 0;
|
||||
}
|
||||
extern "C" int ig_Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int items_count) {
|
||||
return ImGui::Combo(label, current_item, items_separated_by_zeros, items_count) ? 1 : 0;
|
||||
}
|
||||
|
||||
// === Layout ===
|
||||
extern "C" void ig_SameLine(float offset, float spacing) { ImGui::SameLine(offset, spacing); }
|
||||
extern "C" void ig_Separator(void) { ImGui::Separator(); }
|
||||
extern "C" void ig_Spacing(void) { ImGui::Spacing(); }
|
||||
extern "C" void ig_NewLine(void) { ImGui::NewLine(); }
|
||||
extern "C" void ig_PushItemWidth(float w) { ImGui::PushItemWidth(w); }
|
||||
extern "C" void ig_PopItemWidth(void) { ImGui::PopItemWidth(); }
|
||||
|
||||
// === Drawing ===
|
||||
extern "C" void ig_ShowDemoWindow(int* p_open) { ImGui::ShowDemoWindow(p_open ? (bool*)p_open : nullptr); }
|
||||
|
||||
// === Metrics / Info ===
|
||||
extern "C" float ig_GetFramerate(void) { return ImGui::GetIO().Framerate; }
|
||||
extern "C" float ig_GetTime(void) { return (float)ImGui::GetTime(); }
|
||||
extern "C" int ig_GetFrameCount(void) { return ImGui::GetFrameCount(); }
|
||||
|
||||
// === Display ===
|
||||
extern "C" void ig_GetDisplaySize(float* w, float* h) {
|
||||
ImVec2 size = ImGui::GetIO().DisplaySize;
|
||||
*w = size.x; *h = size.y;
|
||||
}
|
||||
extern "C" void ig_GetDisplayFramebufferScale(float* x, float* y) {
|
||||
ImVec2 scale = ImGui::GetIO().DisplayFramebufferScale;
|
||||
*x = scale.x; *y = scale.y;
|
||||
}
|
||||
74
bindings/go/imgui_bridge.h
Normal file
74
bindings/go/imgui_bridge.h
Normal file
@ -0,0 +1,74 @@
|
||||
// imgui_bridge.h — Thin C API bridge for Dear ImGui
|
||||
// This file provides C-callable wrappers around the C++ Dear ImGui API.
|
||||
// It allows languages like Go (via cgo), Rust, Python, etc. to use ImGui.
|
||||
//
|
||||
// Compile with: g++ -c imgui_bridge.cpp -I.. -I../backends -DIMGUI_IMPLEMENTATION
|
||||
// The resulting .o can be linked from any C-compatible FFI.
|
||||
//
|
||||
// Copyright (c) 2024 OwlLogics / imgui_xl
|
||||
// Licensed under MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// === Core ===
|
||||
void ig_CreateContext(void);
|
||||
void ig_DestroyContext(void);
|
||||
void* ig_GetIO(void); // Returns ImGuiIO* as void*
|
||||
void* ig_GetStyle(void); // Returns ImGuiStyle* as void*
|
||||
void ig_NewFrame(void);
|
||||
void ig_Render(void);
|
||||
void* ig_GetDrawData(void); // Returns ImDrawData* as void*
|
||||
const char* ig_GetVersion(void);
|
||||
|
||||
// === Style ===
|
||||
void ig_StyleColorsDark(void);
|
||||
void ig_StyleColorsLight(void);
|
||||
void ig_StyleColorsClassic(void);
|
||||
|
||||
// === Windows ===
|
||||
int ig_Begin(const char* name, int* p_open); // Returns bool (1=visible)
|
||||
void ig_End(void);
|
||||
int ig_BeginChild(const char* str_id, float w, float h, int border); // bool
|
||||
void ig_EndChild(void);
|
||||
|
||||
// === Widgets ===
|
||||
void ig_Text(const char* fmt);
|
||||
void ig_TextColored(float r, float g, float b, float a, const char* fmt);
|
||||
void ig_BulletText(const char* fmt);
|
||||
int ig_Button(const char* label, float w, float h); // bool
|
||||
int ig_InvisibleButton(const char* str_id, float w, float h); // bool
|
||||
int ig_Checkbox(const char* label, int* v); // bool, v is bool*
|
||||
int ig_SliderFloat(const char* label, float* v, float v_min, float v_max); // bool
|
||||
int ig_SliderInt(const char* label, int* v, int v_min, int v_max); // bool
|
||||
int ig_ColorEdit3(const char* label, float* col); // bool, col is float[3]
|
||||
int ig_ColorEdit4(const char* label, float* col, int flags); // bool, col is float[4]
|
||||
int ig_InputText(const char* label, char* buf, int buf_size); // bool
|
||||
int ig_Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int items_count); // bool
|
||||
|
||||
// === Layout ===
|
||||
void ig_SameLine(float offset, float spacing);
|
||||
void ig_Separator(void);
|
||||
void ig_Spacing(void);
|
||||
void ig_NewLine(void);
|
||||
void ig_PushItemWidth(float w);
|
||||
void ig_PopItemWidth(void);
|
||||
|
||||
// === Drawing ===
|
||||
void ig_ShowDemoWindow(int* p_open);
|
||||
|
||||
// === Metrics / Info ===
|
||||
float ig_GetFramerate(void);
|
||||
float ig_GetTime(void);
|
||||
int ig_GetFrameCount(void);
|
||||
|
||||
// === Display ===
|
||||
void ig_GetDisplaySize(float* w, float* h);
|
||||
void ig_GetDisplayFramebufferScale(float* x, float* y);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
38
examples/example_golang/Makefile
Normal file
38
examples/example_golang/Makefile
Normal file
@ -0,0 +1,38 @@
|
||||
# Makefile for the Go ImGui example
|
||||
# Requirements: g++ (or clang++), Go 1.21+, CGO_ENABLED=1
|
||||
#
|
||||
# Usage:
|
||||
# make build - Compile the Go example
|
||||
# make run - Build and run
|
||||
# make clean - Remove build artifacts
|
||||
#
|
||||
# Copyright (c) 2024 OwlLogics / imgui_xl
|
||||
# Licensed under MIT
|
||||
|
||||
GO = go
|
||||
CXX = g++
|
||||
IMGUI_DIR = ../..
|
||||
BRIDGE_DIR = $(IMGUI_DIR)/bindings/go
|
||||
|
||||
CGO_ENABLED = 1
|
||||
GOFLAGS = -trimpath
|
||||
OUTPUT = imgui_go_example
|
||||
|
||||
.PHONY: all build run clean vet fmt
|
||||
|
||||
all: build
|
||||
|
||||
build:
|
||||
CGO_ENABLED=$(CGO_ENABLED) $(GO) build -o $(OUTPUT) . 2>&1 || echo "Build requires a C++ compiler (g++ or clang++) on PATH"
|
||||
|
||||
run: build
|
||||
./$(OUTPUT)
|
||||
|
||||
vet:
|
||||
$(GO) vet ./...
|
||||
|
||||
fmt:
|
||||
$(GO) fmt ./...
|
||||
|
||||
clean:
|
||||
rm -f $(OUTPUT) *.o *.exe
|
||||
7
examples/example_golang/go.mod
Normal file
7
examples/example_golang/go.mod
Normal file
@ -0,0 +1,7 @@
|
||||
module github.com/Turtle-PB/imgui_xl/examples/example_golang
|
||||
|
||||
go 1.21
|
||||
|
||||
require github.com/Turtle-PB/imgui_xl/bindings/go v0.0.0
|
||||
|
||||
replace github.com/Turtle-PB/imgui_xl/bindings/go => ../../bindings/go
|
||||
105
examples/example_golang/main.go
Normal file
105
examples/example_golang/main.go
Normal file
@ -0,0 +1,105 @@
|
||||
// Package main demonstrates using Dear ImGui from Go.
|
||||
// This example runs ImGui in a headless "null" mode — it creates a context,
|
||||
// runs 20 frames of rendering, and prints the output.
|
||||
//
|
||||
// For a full graphical example, pair this with a Go windowing library
|
||||
// (e.g., GLFW, SDL2) and a renderer backend (OpenGL3, Vulkan).
|
||||
//
|
||||
// Build requirements:
|
||||
// - C++ compiler (g++ or clang++) on PATH
|
||||
// - CGO_ENABLED=1 (default when a C compiler is available)
|
||||
//
|
||||
// Build:
|
||||
// cd examples/example_golang
|
||||
// CGO_ENABLED=1 go build -o imgui_go_example
|
||||
// ./imgui_go_example
|
||||
//
|
||||
// Copyright (c) 2024 OwlLogics / imgui_xl
|
||||
// Licensed under MIT
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
imgui "github.com/Turtle-PB/imgui_xl/bindings/go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("=== Dear ImGui Go Example ===")
|
||||
fmt.Printf("ImGui Version: %s\n", imgui.Version())
|
||||
fmt.Println()
|
||||
|
||||
// Create context
|
||||
imgui.CreateContext()
|
||||
defer imgui.DestroyContext()
|
||||
|
||||
// Use dark theme
|
||||
imgui.StyleColorsDark()
|
||||
|
||||
// Run 20 frames in "null" mode (no rendering output)
|
||||
showDemo := true
|
||||
showAnother := false
|
||||
floatVal := 0.0
|
||||
counter := 0
|
||||
|
||||
for frame := 0; frame < 20; frame++ {
|
||||
imgui.NewFrame()
|
||||
|
||||
// Show the ImGui demo window
|
||||
imgui.ShowDemoWindow(&showDemo)
|
||||
|
||||
// Create a custom window
|
||||
visible := imgui.Begin("Hello from Go!", &showDemo)
|
||||
if visible {
|
||||
imgui.Text(fmt.Sprintf("Frame: %d", frame))
|
||||
imgui.Text(fmt.Sprintf("FPS: %.1f", imgui.GetFramerate()))
|
||||
imgui.Separator()
|
||||
|
||||
imgui.Checkbox("Another Window", &showAnother)
|
||||
|
||||
f32Val := float32(floatVal)
|
||||
if imgui.SliderFloat("Float", &f32Val, 0.0, 1.0) {
|
||||
floatVal = float64(f32Val)
|
||||
}
|
||||
|
||||
if imgui.Button("Click Me", 0, 0) {
|
||||
counter++
|
||||
fmt.Printf(" Button clicked! Count: %d\n", counter)
|
||||
}
|
||||
|
||||
imgui.SameLine(0, 4)
|
||||
imgui.Text(fmt.Sprintf("counter = %d", counter))
|
||||
}
|
||||
imgui.End()
|
||||
|
||||
// Show another window toggled by checkbox
|
||||
if showAnother {
|
||||
visible := imgui.Begin("Another Window", &showAnother)
|
||||
if visible {
|
||||
imgui.Text("Hello from the second window!")
|
||||
imgui.Text("This window can be closed via the checkbox.")
|
||||
}
|
||||
imgui.End()
|
||||
}
|
||||
|
||||
imgui.Render()
|
||||
|
||||
if frame == 0 || frame == 9 || frame == 19 {
|
||||
w, h := imgui.GetDisplaySize()
|
||||
fmt.Printf("Frame %2d: Render complete (display: %.0fx%.0f, FPS: %.1f)\n",
|
||||
frame, w, h, imgui.GetFramerate())
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
fmt.Println("=== Done! ===")
|
||||
fmt.Println("20 frames rendered in null mode.")
|
||||
fmt.Println()
|
||||
fmt.Println("To build a graphical Go app with ImGui:")
|
||||
fmt.Println(" 1. Install a Go windowing lib: go get github.com/go-gl/glfw/v3.3/glfw")
|
||||
fmt.Println(" 2. Install an OpenGL Go lib: go get github.com/go-gl/gl/v4.1-core/gl")
|
||||
fmt.Println(" 3. Create a window, init OpenGL,")
|
||||
fmt.Println(" call imgui.CreateContext() + ImGui_ImplOpenGL3_Init()")
|
||||
fmt.Println(" 4. Loop: poll events -> NewFrame -> draw UI -> Render -> RenderDrawData")
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user