func MakeProgram3(vertFname, geomFname, fragFname string) gl.Program { vertShader := MakeShader(gl.VERTEX_SHADER, vertFname) defer vertShader.Delete() geomShader := MakeShader(gl.GEOMETRY_SHADER, geomFname) defer geomShader.Delete() fragShader := MakeShader(gl.FRAGMENT_SHADER, fragFname) defer fragShader.Delete() program := gl.CreateProgram() program.AttachShader(vertShader) program.AttachShader(geomShader) program.AttachShader(fragShader) program.Link() log := program.GetInfoLog() if log != "" { if program.Get(gl.LINK_STATUS) == gl.FALSE { panic(fmt.Sprint("linking ", vertFname, geomFname, fragFname, log)) } else { fmt.Print("linking ", vertFname, geomFname, fragFname, log) } } return program }
func createProgram(vertShaderSrc string, fragShaderSrc string) gl.Program { vertShader := loadShader(gl.VERTEX_SHADER, vertShaderSrc) fragShader := loadShader(gl.FRAGMENT_SHADER, fragShaderSrc) prog := gl.CreateProgram() prog.AttachShader(vertShader) prog.AttachShader(fragShader) prog.Link() if prog.Get(gl.LINK_STATUS) != gl.TRUE { log := prog.GetInfoLog() panic(fmt.Errorf("Failed to link program: %v", log)) } return prog }
func CreateProgram(filenames ...string) gl.Program { program := gl.CreateProgram() for _, fn := range filenames { var shaderType gl.GLenum switch { case strings.HasSuffix(fn, ".vert"): shaderType = gl.VERTEX_SHADER case strings.HasSuffix(fn, ".geom"): shaderType = gl.GEOMETRY_SHADER case strings.HasSuffix(fn, ".frag"): shaderType = gl.FRAGMENT_SHADER default: fmt.Println("Wrong suffix: " + fn) } shader := gl.CreateShader(shaderType) defer shader.Delete() shader.Source(ReadFile(fn)) shader.Compile() if info := shader.GetInfoLog(); info != "" { log.Fatal(info) } program.AttachShader(shader) defer program.DetachShader(shader) } program.Link() if info := program.GetInfoLog(); info != "" { log.Fatal(info) } return program }
func MakeProgram(vertFname, fragFname string) gl.Program { vao := gl.GenVertexArray() vao.Bind() vertShader := MakeShader(gl.VERTEX_SHADER, vertFname) defer vertShader.Delete() fragShader := MakeShader(gl.FRAGMENT_SHADER, fragFname) defer fragShader.Delete() program := gl.CreateProgram() program.AttachShader(vertShader) program.AttachShader(fragShader) program.Link() linkstat := program.Get(gl.LINK_STATUS) if linkstat != 1 { // log.Panic("Program link failed, sources=", vertFname, fragFname, "\nstatus=", linkstat, "\nInfo log: ", program.GetInfoLog()) } program.Validate() valstat := program.Get(gl.VALIDATE_STATUS) if valstat != 1 { // log.Panic("Program validation failed: ", valstat) } log := program.GetInfoLog() if log != "" { if program.Get(gl.LINK_STATUS) == gl.FALSE { panic(fmt.Sprint("linking ", vertFname, fragFname, log)) } else { fmt.Print("linking ", vertFname, fragFname, log) } } vao.Delete() return program }
func main() { glfw.SetErrorCallback(errorCallback) // lock glfw/gl calls to a single thread runtime.LockOSThread() runtime.GOMAXPROCS(8) // Render, read commands, send input, extra for file loading, etc if !glfw.Init() { panic("Could not init glfw!") } defer glfw.Terminate() glfw.WindowHint(glfw.ContextVersionMajor, 3) glfw.WindowHint(glfw.ContextVersionMinor, 3) glfw.WindowHint(glfw.OpenglForwardCompatible, glfw.True) glfw.WindowHint(glfw.OpenglProfile, glfw.OpenglCoreProfile) window, err := glfw.CreateWindow(800, 600, "Example", nil, nil) if err != nil { panic(err) } window.SetFramebufferSizeCallback(func(w *glfw.Window, width, height int) { fmt.Printf("Framebuffer size is now %vx%v\n", width, height) // Keep aspect ratio from camwidth/camheight camRatio := camWidth / camHeight bufRatio := float32(width) / float32(height) var newWidth, newHeight float32 switch { case camRatio > bufRatio: newHeight = float32(width) / camRatio newWidth = float32(width) case bufRatio > camRatio: newWidth = float32(height) * camRatio newHeight = float32(height) } fmt.Printf("Viewport size is now %vx%v; cam ratio is %v; viewport ratio is %v;\n", newWidth, newHeight, camRatio, newWidth/newHeight) gl.Viewport((width-int(newWidth))/2, (height-int(newHeight))/2, int(newWidth), int(newHeight)) }) defer window.Destroy() window.MakeContextCurrent() glfw.SwapInterval(1) gl.Init() // Enable blending gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) vao := gl.GenVertexArray() vao.Bind() vbo := gl.GenBuffer() vbo.Bind(gl.ARRAY_BUFFER) verticies := []float32{-0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, -0.5} gl.BufferData(gl.ARRAY_BUFFER, len(verticies)*4, verticies, gl.STATIC_DRAW) vertex_shader := gl.CreateShader(gl.VERTEX_SHADER) vertex_shader.Source(vertex) vertex_shader.Compile() fmt.Println(vertex_shader.GetInfoLog()) defer vertex_shader.Delete() fragment_shader := gl.CreateShader(gl.FRAGMENT_SHADER) fragment_shader.Source(fragment) fragment_shader.Compile() fmt.Println(fragment_shader.GetInfoLog()) defer fragment_shader.Delete() program := gl.CreateProgram() program.AttachShader(vertex_shader) program.AttachShader(fragment_shader) program.BindFragDataLocation(0, "outColor") program.Link() program.Use() defer program.Delete() positionAttrib := program.GetAttribLocation("position") positionAttrib.AttribPointer(2, gl.FLOAT, false, 0, nil) positionAttrib.EnableArray() defer positionAttrib.DisableArray() modelMat := program.GetUniformLocation("modelView") projMat := program.GetUniformLocation("projection") spriteSize := program.GetUniformLocation("size") cmd := exec.Command(os.Args[1], os.Args[2:]...) stdoutReader, stdoutWriter := io.Pipe() cmd.Stdout = stdoutWriter input := bufio.NewReader(stdoutReader) stdinReader, stdinWriter := io.Pipe() cmd.Stdin = stdinReader stderr, err := cmd.StderrPipe() chkErr(err) go io.Copy(os.Stderr, stderr) err = cmd.Start() chkErr(err) window.SetKeyCallback(handleKey) go func() { runtime.LockOSThread() for !window.ShouldClose() { sendInput(stdinWriter) //fmt.Fprintf(stdinWriter, "T %v\n", time.Now()) <-ticks readCommands(input) } }() frameCnt := 0 queueDepth := 0 then := time.Now() for !window.ShouldClose() { frameCnt++ queueDepth += len(commandBus) if frameCnt%120 == 0 { fmt.Printf("Queue depth: %v. Render time: %v. Decode time: %v.\n", queueDepth/120, time.Since(then)/120, decodeTime/time.Duration(decodes)) queueDepth = 0 then = time.Now() decodeTime = time.Duration(0) decodes = 0 } for len(commandBus) > 0 { (<-commandBus)() } halfwidth := camWidth / 2.0 halfheight := camHeight / 2.0 projection := mathgl.Ortho2D(camera.x-halfwidth, camera.x+halfwidth, camera.y+halfheight, camera.y-halfheight) projection = mathgl.Scale3D(camera.sx, camera.sy, 1).Mul4(projection) projection = mathgl.HomogRotate3DZ(camera.rot).Mul4(projection) projMat.UniformMatrix4f(false, (*[16]float32)(&projection)) gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) for _, sprite := range sprites { sMat := mathgl.Scale3D(sprite.sx, sprite.sy, 1) sMat = mathgl.HomogRotate3DZ(sprite.rot).Mul4(sMat) sMat = mathgl.Translate3D(sprite.x, sprite.y, sprite.z).Mul4(sMat) // temp hack bank in sprite.bank = 1 sMap := findSMap(sprite.smap) spriteSize.Uniform2f(float32(sMap.getWidth()*sprite.cellwidth), float32(sMap.getHeight()*sprite.cellheight)) modelMat.UniformMatrix4f(false, (*[16]float32)(&sMat)) gl.DrawArrays(gl.TRIANGLE_FAN, 0, 4) } window.SwapBuffers() glfw.PollEvents() if window.GetKey(glfw.KeyEscape) == glfw.Press { window.SetShouldClose(true) } } }
func NewBasicMaterial(vertexShader, fragmentShader string) *BasicMaterial { return &BasicMaterial{Program: Program{gl.CreateProgram()}, vertexShader: vertexShader, fragmentShader: fragmentShader} }
func NewParticleSystem(w *gamestate.World, numParticles int, Origin mgl.Vec3, initialSpeed, MaxLifetime float32) *ParticleSystem { vertices := make([]ParticleVertex, numParticles) directions := make([]NonTransformBuffer, numParticles) for i := range vertices { dir := mgl.Vec3{rand.Float32()*2 - 1, rand.Float32()*2 - 1, rand.Float32()*2 - 1} for dir.Len() > 1 { dir = mgl.Vec3{rand.Float32()*2 - 1, rand.Float32()*2 - 1, rand.Float32()*2 - 1} } dir = dir.Mul(initialSpeed) vertices[i] = ParticleVertex{ Pos1: Origin, Pos2: Origin.Sub(dir), Lifetime: rand.Float32() * MaxLifetime, } directions[i] = NonTransformBuffer{dir} } buffer1, buffer2, nonTransformBuffer := gl.GenBuffer(), gl.GenBuffer(), gl.GenBuffer() nonTransformBuffer.Bind(gl.ARRAY_BUFFER) gl.BufferData(gl.ARRAY_BUFFER, helpers.ByteSizeOfSlice(directions), directions, gl.STATIC_DRAW) buffer1.Bind(gl.ARRAY_BUFFER) gl.BufferData(gl.ARRAY_BUFFER, helpers.ByteSizeOfSlice(vertices), vertices, gl.STREAM_DRAW) buffer2.Bind(gl.ARRAY_BUFFER) gl.BufferData(gl.ARRAY_BUFFER, helpers.ByteSizeOfSlice(vertices), uintptr(0), gl.STREAM_DRAW) shapeData := CreateShapeDataBuffer() TransformProg := gl.CreateProgram() shader := helpers.MakeShader(gl.VERTEX_SHADER, "ParticleTFF.vs") TransformProg.AttachShader(shader) TransformProg.TransformFeedbackVaryings([]string{"v_Pos1", "v_Pos2", "v_Lifetime"}, gl.INTERLEAVED_ATTRIBS) TransformProg.Link() shader.Delete() TransformProg.Use() TransformLoc := ProgramLocations{} helpers.BindLocations("particle transform", TransformProg, &TransformLoc) renderProgram := helpers.MakeProgram("Particle.vs", "Particle.fs") renderProgram.Use() RenderLoc := RenderProgramLocations{} helpers.BindLocations("particle render", renderProgram, &RenderLoc) vaoTff1 := gl.GenVertexArray() vaoTff2 := gl.GenVertexArray() vaoRender1 := gl.GenVertexArray() vaoRender2 := gl.GenVertexArray() ps := ParticleSystem{ TransformProg: TransformProg, TransformLoc: TransformLoc, RenderProg: renderProgram, RenderLoc: RenderLoc, VaoTff1: vaoTff1, VaoTff2: vaoTff2, VaoRender1: vaoRender1, VaoRender2: vaoRender2, Data1: buffer1, Data2: buffer2, ShapeData: shapeData, NonTransformBuffer: nonTransformBuffer, NumParticles: numParticles, Origin: Origin, Gravity: -9.81 / 200, InitialSpeed: initialSpeed, MaxLifetime: MaxLifetime, } min_h, max_h := w.HeightMap.Bounds() W := float32(w.HeightMap.W) H := float32(w.HeightMap.H) TransformProg.Use() ps.SetUniforms() ps.SetVaos() TransformProg.Use() ps.TransformLoc.HeightMap.Uniform1i(constants.TextureHeightMap) ps.TransformLoc.LowerBound.Uniform3f(0, 0, min_h) ps.TransformLoc.UpperBound.Uniform3f(W, H, max_h) return &ps }