-
-
Save nikomartn/13337ddf6885b1c45000bfb4861dbf26 to your computer and use it in GitHub Desktop.
cgo for windows!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The go experience in windows is very suboptimal, you need to install MSYS2 and mingw and what else.. | |
And cross your fingers to get it working. | |
But, wsl2 comes to the rescue, even for things like go-gl! | |
1. Install wsl2 | |
2. (Ubuntu) sudo apt update && sudo apt install mingw-w64 | |
3. .bashrc => alias wingo='GOOS=windows GOARCH=amd64 CC=x86_64-w64-mingw32-gcc CGO_ENABLED=1 go' | |
4. wingo build | |
And thats it, you can make WSL your toolchain for Windows go executables. | |
As an example, try to wingo build the attached opengl example found in this tutorial: | |
https://kylewbanks.com/blog/tutorial-opengl-with-golang-part-1-hello-opengl | |
It will take some time to mingw to compile and link the whole opengl libraries, but after the first compilation, go sould | |
cache the artefacts, consecuent builds will be faster. | |
This could be extended with Docker for more complex deployments. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"log" | |
"runtime" | |
"strings" | |
"github.com/go-gl/gl/v4.1-core/gl" // OR: github.com/go-gl/gl/v2.1/gl | |
"github.com/go-gl/glfw/v3.2/glfw" | |
) | |
const ( | |
width = 500 | |
height = 500 | |
vertexShaderSource = ` | |
#version 410 | |
in vec3 vp; | |
void main() { | |
gl_Position = vec4(vp, 1.0); | |
} | |
` + "\x00" | |
fragmentShaderSource = ` | |
#version 410 | |
out vec4 frag_colour; | |
void main() { | |
frag_colour = vec4(1, 1, 1, 1.0); | |
} | |
` + "\x00" | |
) | |
var ( | |
triangle = []float32{ | |
0, 0.5, 0, | |
-0.5, -0.5, 0, | |
0.5, -0.5, 0, | |
} | |
) | |
func main() { | |
runtime.LockOSThread() | |
window := initGlfw() | |
defer glfw.Terminate() | |
program := initOpenGL() | |
vao := makeVao(triangle) | |
for !window.ShouldClose() { | |
draw(vao, window, program) | |
} | |
} | |
func draw(vao uint32, window *glfw.Window, program uint32) { | |
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) | |
gl.UseProgram(program) | |
gl.BindVertexArray(vao) | |
gl.DrawArrays(gl.TRIANGLES, 0, int32(len(triangle)/3)) | |
glfw.PollEvents() | |
window.SwapBuffers() | |
} | |
// initGlfw initializes glfw and returns a Window to use. | |
func initGlfw() *glfw.Window { | |
if err := glfw.Init(); err != nil { | |
panic(err) | |
} | |
glfw.WindowHint(glfw.Resizable, glfw.False) | |
glfw.WindowHint(glfw.ContextVersionMajor, 4) | |
glfw.WindowHint(glfw.ContextVersionMinor, 1) | |
glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) | |
glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True) | |
window, err := glfw.CreateWindow(width, height, "Conway's Game of Life", nil, nil) | |
if err != nil { | |
panic(err) | |
} | |
window.MakeContextCurrent() | |
return window | |
} | |
// initOpenGL initializes OpenGL and returns an intiialized program. | |
func initOpenGL() uint32 { | |
if err := gl.Init(); err != nil { | |
panic(err) | |
} | |
version := gl.GoStr(gl.GetString(gl.VERSION)) | |
log.Println("OpenGL version", version) | |
vertexShader, err := compileShader(vertexShaderSource, gl.VERTEX_SHADER) | |
if err != nil { | |
panic(err) | |
} | |
fragmentShader, err := compileShader(fragmentShaderSource, gl.FRAGMENT_SHADER) | |
if err != nil { | |
panic(err) | |
} | |
prog := gl.CreateProgram() | |
gl.AttachShader(prog, vertexShader) | |
gl.AttachShader(prog, fragmentShader) | |
gl.LinkProgram(prog) | |
return prog | |
} | |
// makeVao initializes and returns a vertex array from the points provided. | |
func makeVao(points []float32) uint32 { | |
var vbo uint32 | |
gl.GenBuffers(1, &vbo) | |
gl.BindBuffer(gl.ARRAY_BUFFER, vbo) | |
gl.BufferData(gl.ARRAY_BUFFER, 4*len(points), gl.Ptr(points), gl.STATIC_DRAW) | |
var vao uint32 | |
gl.GenVertexArrays(1, &vao) | |
gl.BindVertexArray(vao) | |
gl.EnableVertexAttribArray(0) | |
gl.BindBuffer(gl.ARRAY_BUFFER, vbo) | |
gl.VertexAttribPointer(0, 3, gl.FLOAT, false, 0, nil) | |
return vao | |
} | |
func compileShader(source string, shaderType uint32) (uint32, error) { | |
shader := gl.CreateShader(shaderType) | |
csources, free := gl.Strs(source) | |
gl.ShaderSource(shader, 1, csources, nil) | |
free() | |
gl.CompileShader(shader) | |
var status int32 | |
gl.GetShaderiv(shader, gl.COMPILE_STATUS, &status) | |
if status == gl.FALSE { | |
var logLength int32 | |
gl.GetShaderiv(shader, gl.INFO_LOG_LENGTH, &logLength) | |
log := strings.Repeat("\x00", int(logLength+1)) | |
gl.GetShaderInfoLog(shader, logLength, nil, gl.Str(log)) | |
return 0, fmt.Errorf("failed to compile %v: %v", source, log) | |
} | |
return shader, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment