Initial Commit
This commit is contained in:
commit
429a17cbf5
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/ui.iml" filepath="$PROJECT_DIR$/.idea/ui.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
9
.idea/ui.iml
generated
Normal file
9
.idea/ui.iml
generated
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="Go" enabled="true" />
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
12
go.mod
Normal file
12
go.mod
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
module main
|
||||||
|
|
||||||
|
go 1.23.0
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71 // indirect
|
||||||
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a // indirect
|
||||||
|
github.com/go-gl/gltext v0.0.0-20170328174336-01a355945a70 // indirect
|
||||||
|
github.com/go-gl/mathgl v1.1.0 // indirect
|
||||||
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||||
|
golang.org/x/image v0.21.0 // indirect
|
||||||
|
)
|
14
go.sum
Normal file
14
go.sum
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71 h1:5BVwOaUSBTlVZowGO6VZGw2H/zl9nrd3eCZfYV+NfQA=
|
||||||
|
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw=
|
||||||
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a h1:vxnBhFDDT+xzxf1jTJKMKZw3H0swfWk9RpWbBbDK5+0=
|
||||||
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
|
github.com/go-gl/gltext v0.0.0-20170328174336-01a355945a70 h1:jLHSn7wgzCXTsZoldNrhgFS5fasJxb8Htn+iaYsZt88=
|
||||||
|
github.com/go-gl/gltext v0.0.0-20170328174336-01a355945a70/go.mod h1:KpCmHMLAPxpCBuDN9Tp7mjJA7lwFZNc2bZ0rCi/X6yc=
|
||||||
|
github.com/go-gl/mathgl v1.1.0 h1:0lzZ+rntPX3/oGrDzYGdowSLC2ky8Osirvf5uAwfIEA=
|
||||||
|
github.com/go-gl/mathgl v1.1.0/go.mod h1:yhpkQzEiH9yPyxDUGzkmgScbaBVlhC06qodikEM0ZwQ=
|
||||||
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||||
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||||
|
golang.org/x/image v0.0.0-20190321063152-3fc05d484e9f/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||||
|
golang.org/x/image v0.21.0 h1:c5qV36ajHpdj4Qi0GnE0jUc/yuo33OLFaa0d+crTD5s=
|
||||||
|
golang.org/x/image v0.21.0/go.mod h1:vUbsLavqK/W303ZroQQVKQ+Af3Yl6Uz1Ppu5J/cLz78=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
483
stuff.go
Normal file
483
stuff.go
Normal file
@ -0,0 +1,483 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/go-gl/gl/v4.1-core/gl"
|
||||||
|
"github.com/go-gl/glfw/v3.3/glfw"
|
||||||
|
"github.com/go-gl/gltext"
|
||||||
|
"github.com/go-gl/mathgl/mgl32"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// GLFW event handling must run on the main OS thread
|
||||||
|
runtime.LockOSThread()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Position represents a 2D position
|
||||||
|
type Position struct {
|
||||||
|
X, Y float32
|
||||||
|
}
|
||||||
|
|
||||||
|
// Size represents the width and height of a UI element
|
||||||
|
type Size struct {
|
||||||
|
Width, Height float32
|
||||||
|
}
|
||||||
|
|
||||||
|
// EventType represents the type of an event
|
||||||
|
type EventType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
EventTypeClick EventType = iota
|
||||||
|
EventTypeMouseMove
|
||||||
|
EventTypeHover
|
||||||
|
)
|
||||||
|
|
||||||
|
// Event represents an input event
|
||||||
|
type Event struct {
|
||||||
|
Type EventType
|
||||||
|
Position Position
|
||||||
|
}
|
||||||
|
|
||||||
|
// UIElement defines the interface for UI elements
|
||||||
|
type UIElement interface {
|
||||||
|
Draw()
|
||||||
|
Update()
|
||||||
|
HandleEvent(event Event)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Container defines the interface for UI containers
|
||||||
|
type Container interface {
|
||||||
|
UIElement
|
||||||
|
AddChild(UIElement)
|
||||||
|
RemoveChild(UIElement)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Context manages the OpenGL context and resources
|
||||||
|
type Context struct {
|
||||||
|
shaderProgram uint32
|
||||||
|
font *gltext.Font
|
||||||
|
windowWidth int
|
||||||
|
windowHeight int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewContext(windowWidth, windowHeight int) *Context {
|
||||||
|
return &Context{
|
||||||
|
windowWidth: windowWidth,
|
||||||
|
windowHeight: windowHeight,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) InitOpenGL() {
|
||||||
|
if err := gl.Init(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
version := gl.GoStr(gl.GetString(gl.VERSION))
|
||||||
|
fmt.Println("OpenGL version", version)
|
||||||
|
|
||||||
|
// Initialize shader program
|
||||||
|
c.shaderProgram = NewShaderProgram(vertexShaderSource, fragmentShaderSource)
|
||||||
|
|
||||||
|
// Load font using gltext
|
||||||
|
fontData, err := os.Open("arial.ttf")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer fontData.Close()
|
||||||
|
|
||||||
|
// Load the truetype font: specify scale, rune range (ASCII), and direction
|
||||||
|
font, err := gltext.LoadTruetype(fontData, 24, 32, 127, gltext.LeftToRight)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
c.font = font
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) Clear() {
|
||||||
|
gl.ClearColor(0.0, 0.0, 0.0, 1.0)
|
||||||
|
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) SwapBuffers(window *glfw.Window) {
|
||||||
|
window.SwapBuffers()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Window represents the main application window
|
||||||
|
type Window struct {
|
||||||
|
width int
|
||||||
|
height int
|
||||||
|
title string
|
||||||
|
transparent bool
|
||||||
|
panels []*Panel
|
||||||
|
glContext *Context
|
||||||
|
glfwWindow *glfw.Window
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWindow(width, height int, title string) *Window {
|
||||||
|
if err := glfw.Init(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
glfw.WindowHint(glfw.ContextVersionMajor, 4)
|
||||||
|
glfw.WindowHint(glfw.ContextVersionMinor, 1)
|
||||||
|
glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)
|
||||||
|
glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True)
|
||||||
|
|
||||||
|
glfwWindow, err := glfw.CreateWindow(width, height, title, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
glfwWindow.MakeContextCurrent()
|
||||||
|
|
||||||
|
return &Window{
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
title: title,
|
||||||
|
panels: []*Panel{},
|
||||||
|
glfwWindow: glfwWindow,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) SetTransparent(t bool) {
|
||||||
|
w.transparent = t
|
||||||
|
// Apply transparency settings if needed
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) DefineContext() *Context {
|
||||||
|
w.glContext = NewContext(w.width, w.height)
|
||||||
|
w.glContext.InitOpenGL()
|
||||||
|
return w.glContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) CreatePanel() *Panel {
|
||||||
|
panel := NewPanel()
|
||||||
|
w.panels = append(w.panels, panel)
|
||||||
|
return panel
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) registerCallbacks() {
|
||||||
|
w.glfwWindow.SetCursorPosCallback(w.cursorPosCallback)
|
||||||
|
w.glfwWindow.SetMouseButtonCallback(w.mouseButtonCallback)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) cursorPosCallback(window *glfw.Window, xpos float64, ypos float64) {
|
||||||
|
event := Event{
|
||||||
|
Type: EventTypeMouseMove,
|
||||||
|
Position: Position{X: float32(xpos), Y: float32(ypos)},
|
||||||
|
}
|
||||||
|
w.handleEvent(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) mouseButtonCallback(window *glfw.Window, button glfw.MouseButton, action glfw.Action, mods glfw.ModifierKey) {
|
||||||
|
if button == glfw.MouseButtonLeft && action == glfw.Press {
|
||||||
|
xpos, ypos := window.GetCursorPos()
|
||||||
|
event := Event{
|
||||||
|
Type: EventTypeClick,
|
||||||
|
Position: Position{X: float32(xpos), Y: float32(ypos)},
|
||||||
|
}
|
||||||
|
w.handleEvent(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) handleEvent(event Event) {
|
||||||
|
for _, panel := range w.panels {
|
||||||
|
panel.HandleEvent(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) update() {
|
||||||
|
for _, panel := range w.panels {
|
||||||
|
panel.Update()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) draw() {
|
||||||
|
for _, panel := range w.panels {
|
||||||
|
panel.Draw()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) Start() {
|
||||||
|
w.registerCallbacks()
|
||||||
|
for !w.glfwWindow.ShouldClose() {
|
||||||
|
glfw.PollEvents()
|
||||||
|
w.glContext.Clear()
|
||||||
|
|
||||||
|
w.update()
|
||||||
|
w.draw()
|
||||||
|
|
||||||
|
w.glContext.SwapBuffers(w.glfwWindow)
|
||||||
|
}
|
||||||
|
glfw.Terminate()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Panel is a container for UI elements
|
||||||
|
type Panel struct {
|
||||||
|
children []UIElement
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPanel() *Panel {
|
||||||
|
return &Panel{
|
||||||
|
children: []UIElement{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Panel) AddChild(e UIElement) {
|
||||||
|
p.children = append(p.children, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Panel) RemoveChild(e UIElement) {
|
||||||
|
// Implement child removal logic if needed
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Panel) Draw() {
|
||||||
|
for _, child := range p.children {
|
||||||
|
child.Draw()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Panel) Update() {
|
||||||
|
for _, child := range p.children {
|
||||||
|
child.Update()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Panel) HandleEvent(event Event) {
|
||||||
|
for _, child := range p.children {
|
||||||
|
child.HandleEvent(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Button is a clickable UI element
|
||||||
|
type Button struct {
|
||||||
|
label string
|
||||||
|
onClick func()
|
||||||
|
Position
|
||||||
|
Size
|
||||||
|
isHovered bool
|
||||||
|
context *Context
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewButton(label string, onClick func(), context *Context) *Button {
|
||||||
|
return &Button{
|
||||||
|
label: label,
|
||||||
|
onClick: onClick,
|
||||||
|
context: context,
|
||||||
|
Position: Position{X: 0, Y: 0},
|
||||||
|
Size: Size{Width: 100, Height: 50},
|
||||||
|
isHovered: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Button) contains(pos Position) bool {
|
||||||
|
return pos.X >= b.Position.X && pos.X <= b.Position.X+b.Size.Width &&
|
||||||
|
pos.Y >= b.Position.Y && pos.Y <= b.Position.Y+b.Size.Height
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Button) Draw() {
|
||||||
|
var color [4]float32
|
||||||
|
if b.isHovered {
|
||||||
|
color = [4]float32{0.7, 0.7, 0.7, 1.0} // Lighter when hovered
|
||||||
|
} else {
|
||||||
|
color = [4]float32{0.5, 0.5, 0.5, 1.0}
|
||||||
|
}
|
||||||
|
|
||||||
|
rect := NewRectangle(b.Position.X, b.Position.Y, b.Size.Width, b.Size.Height, color, b.context)
|
||||||
|
rect.Draw()
|
||||||
|
rect.Destroy()
|
||||||
|
|
||||||
|
// Draw the label
|
||||||
|
x := b.Position.X + 10
|
||||||
|
y := b.Position.Y + b.Size.Height/2 + 8 // Approximate vertical centering
|
||||||
|
b.context.font.Printf(x, y, b.label)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Button) Update() {
|
||||||
|
// Update the button if needed
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Button) HandleEvent(event Event) {
|
||||||
|
switch event.Type {
|
||||||
|
case EventTypeClick:
|
||||||
|
if b.contains(event.Position) {
|
||||||
|
b.onClick()
|
||||||
|
}
|
||||||
|
case EventTypeMouseMove:
|
||||||
|
if b.contains(event.Position) {
|
||||||
|
if !b.isHovered {
|
||||||
|
b.isHovered = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if b.isHovered {
|
||||||
|
b.isHovered = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rectangle is used to draw a rectangle using OpenGL
|
||||||
|
type Rectangle struct {
|
||||||
|
Position
|
||||||
|
Size
|
||||||
|
Color [4]float32
|
||||||
|
vao uint32
|
||||||
|
vbo uint32
|
||||||
|
shaderProgram uint32
|
||||||
|
context *Context
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRectangle(x, y, width, height float32, color [4]float32, context *Context) *Rectangle {
|
||||||
|
rect := &Rectangle{
|
||||||
|
Position: Position{X: x, Y: y},
|
||||||
|
Size: Size{Width: width, Height: height},
|
||||||
|
Color: color,
|
||||||
|
shaderProgram: context.shaderProgram,
|
||||||
|
context: context,
|
||||||
|
}
|
||||||
|
rect.initOpenGL()
|
||||||
|
return rect
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Rectangle) initOpenGL() {
|
||||||
|
vertices := []float32{
|
||||||
|
r.Position.X, r.Position.Y, 0.0,
|
||||||
|
r.Position.X + r.Size.Width, r.Position.Y, 0.0,
|
||||||
|
r.Position.X + r.Size.Width, r.Position.Y + r.Size.Height, 0.0,
|
||||||
|
r.Position.X, r.Position.Y + r.Size.Height, 0.0,
|
||||||
|
}
|
||||||
|
indices := []uint32{
|
||||||
|
0, 1, 2,
|
||||||
|
2, 3, 0,
|
||||||
|
}
|
||||||
|
gl.GenVertexArrays(1, &r.vao)
|
||||||
|
gl.BindVertexArray(r.vao)
|
||||||
|
|
||||||
|
gl.GenBuffers(1, &r.vbo)
|
||||||
|
gl.BindBuffer(gl.ARRAY_BUFFER, r.vbo)
|
||||||
|
gl.BufferData(gl.ARRAY_BUFFER, len(vertices)*4, gl.Ptr(vertices), gl.STATIC_DRAW)
|
||||||
|
|
||||||
|
var ebo uint32
|
||||||
|
gl.GenBuffers(1, &ebo)
|
||||||
|
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebo)
|
||||||
|
gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(indices)*4, gl.Ptr(indices), gl.STATIC_DRAW)
|
||||||
|
|
||||||
|
gl.VertexAttribPointer(0, 3, gl.FLOAT, false, 3*4, gl.PtrOffset(0))
|
||||||
|
gl.EnableVertexAttribArray(0)
|
||||||
|
|
||||||
|
gl.BindVertexArray(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Rectangle) Draw() {
|
||||||
|
gl.UseProgram(r.shaderProgram)
|
||||||
|
|
||||||
|
// Set uniforms
|
||||||
|
model := mgl32.Ident4()
|
||||||
|
projection := mgl32.Ortho2D(0, float32(r.context.windowWidth), float32(r.context.windowHeight), 0)
|
||||||
|
|
||||||
|
modelLoc := gl.GetUniformLocation(r.shaderProgram, gl.Str("model\x00"))
|
||||||
|
projectionLoc := gl.GetUniformLocation(r.shaderProgram, gl.Str("projection\x00"))
|
||||||
|
colorLoc := gl.GetUniformLocation(r.shaderProgram, gl.Str("color\x00"))
|
||||||
|
|
||||||
|
gl.UniformMatrix4fv(modelLoc, 1, false, &model[0])
|
||||||
|
gl.UniformMatrix4fv(projectionLoc, 1, false, &projection[0])
|
||||||
|
gl.Uniform4fv(colorLoc, 1, &r.Color[0])
|
||||||
|
|
||||||
|
gl.BindVertexArray(r.vao)
|
||||||
|
gl.DrawElements(gl.TRIANGLES, 6, gl.UNSIGNED_INT, gl.PtrOffset(0))
|
||||||
|
gl.BindVertexArray(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Rectangle) Destroy() {
|
||||||
|
gl.DeleteVertexArrays(1, &r.vao)
|
||||||
|
gl.DeleteBuffers(1, &r.vbo)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shader sources
|
||||||
|
var vertexShaderSource = `
|
||||||
|
#version 410 core
|
||||||
|
layout(location = 0) in vec3 position;
|
||||||
|
uniform mat4 model;
|
||||||
|
uniform mat4 projection;
|
||||||
|
void main() {
|
||||||
|
gl_Position = projection * model * vec4(position, 1.0);
|
||||||
|
}
|
||||||
|
` + "\x00"
|
||||||
|
|
||||||
|
var fragmentShaderSource = `
|
||||||
|
#version 410 core
|
||||||
|
out vec4 fragColor;
|
||||||
|
uniform vec4 color;
|
||||||
|
void main() {
|
||||||
|
fragColor = color;
|
||||||
|
}
|
||||||
|
` + "\x00"
|
||||||
|
|
||||||
|
// NewShaderProgram compiles and links the vertex and fragment shaders
|
||||||
|
func NewShaderProgram(vertexShaderSource, fragmentShaderSource string) uint32 {
|
||||||
|
vertexShader := gl.CreateShader(gl.VERTEX_SHADER)
|
||||||
|
cvertexShaderSource, freeVertex := gl.Strs(vertexShaderSource)
|
||||||
|
gl.ShaderSource(vertexShader, 1, cvertexShaderSource, nil)
|
||||||
|
freeVertex()
|
||||||
|
gl.CompileShader(vertexShader)
|
||||||
|
|
||||||
|
var status int32
|
||||||
|
gl.GetShaderiv(vertexShader, gl.COMPILE_STATUS, &status)
|
||||||
|
if status == gl.FALSE {
|
||||||
|
var logLength int32
|
||||||
|
gl.GetShaderiv(vertexShader, gl.INFO_LOG_LENGTH, &logLength)
|
||||||
|
log := strings.Repeat("\x00", int(logLength+1))
|
||||||
|
gl.GetShaderInfoLog(vertexShader, logLength, nil, gl.Str(log))
|
||||||
|
panic(fmt.Sprintf("failed to compile vertex shader: %v", log))
|
||||||
|
}
|
||||||
|
|
||||||
|
fragmentShader := gl.CreateShader(gl.FRAGMENT_SHADER)
|
||||||
|
cfragmentShaderSource, freeFragment := gl.Strs(fragmentShaderSource)
|
||||||
|
gl.ShaderSource(fragmentShader, 1, cfragmentShaderSource, nil)
|
||||||
|
freeFragment()
|
||||||
|
gl.CompileShader(fragmentShader)
|
||||||
|
|
||||||
|
gl.GetShaderiv(fragmentShader, gl.COMPILE_STATUS, &status)
|
||||||
|
if status == gl.FALSE {
|
||||||
|
var logLength int32
|
||||||
|
gl.GetShaderiv(fragmentShader, gl.INFO_LOG_LENGTH, &logLength)
|
||||||
|
log := strings.Repeat("\x00", int(logLength+1))
|
||||||
|
gl.GetShaderInfoLog(fragmentShader, logLength, nil, gl.Str(log))
|
||||||
|
panic(fmt.Sprintf("failed to compile fragment shader: %v", log))
|
||||||
|
}
|
||||||
|
|
||||||
|
program := gl.CreateProgram()
|
||||||
|
gl.AttachShader(program, vertexShader)
|
||||||
|
gl.AttachShader(program, fragmentShader)
|
||||||
|
gl.LinkProgram(program)
|
||||||
|
|
||||||
|
gl.GetProgramiv(program, gl.LINK_STATUS, &status)
|
||||||
|
if status == gl.FALSE {
|
||||||
|
var logLength int32
|
||||||
|
gl.GetProgramiv(program, gl.INFO_LOG_LENGTH, &logLength)
|
||||||
|
log := strings.Repeat("\x00", int(logLength+1))
|
||||||
|
gl.GetProgramInfoLog(program, logLength, nil, gl.Str(log))
|
||||||
|
panic(fmt.Sprintf("failed to link program: %v", log))
|
||||||
|
}
|
||||||
|
|
||||||
|
gl.DeleteShader(vertexShader)
|
||||||
|
gl.DeleteShader(fragmentShader)
|
||||||
|
|
||||||
|
return program
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
window := NewWindow(800, 600, "Demo Window")
|
||||||
|
window.SetTransparent(true)
|
||||||
|
context := window.DefineContext()
|
||||||
|
|
||||||
|
panel := window.CreatePanel()
|
||||||
|
|
||||||
|
button := NewButton("Click me!", func() { fmt.Println("Button pressed!") }, context)
|
||||||
|
button.Position = Position{X: 100, Y: 100}
|
||||||
|
button.Size = Size{Width: 200, Height: 50}
|
||||||
|
panel.AddChild(button)
|
||||||
|
|
||||||
|
window.Start()
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user