func OpenWindow(width, height int, caption string) *glfw.Window { // OpenGL haluaa että sitä käytetään aina samasta threadista // muuten tulee satunnaisia segfaultteja runtime.LockOSThread() glfw.Init() // luodaan ikkuna w, err := glfw.CreateWindow(width, height, caption, nil, nil) if err != nil { log.Fatal(err) } w.MakeContextCurrent() gl.Init() // Jotta painalluksista kerrottaisiin vaikka ne olisivat jo päättyneet w.SetInputMode(glfw.StickyKeys, glfw.True) w.SetInputMode(glfw.StickyMouseButtons, glfw.True) // läpinäkyvyys päälle (non-premultiplied alpha) gl.Enable(gl.BLEND) gl.BlendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD) gl.BlendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ZERO) return w }
func (ps *ParticleSystem) DoStep(gs *gamestate.GameState) { ps.TransformProg.Use() ps.VaoTff1.Bind() gl.Enable(gl.RASTERIZER_DISCARD) defer gl.Disable(gl.RASTERIZER_DISCARD) // ps.Data1.Bind(gl.ARRAY_BUFFER) // SetAttribPointers(&ps.TransformLoc, &ParticleVertex{}, false) //var orientation mgl.Quat = gs.Player.Camera.Orientation var model mgl.Mat4 = gs.Camera.Model() pPos := model.Mul4x1(mgl.Vec4{1, -1, 0, 1}) ps.TransformLoc.Origin.Uniform3f(pPos[0], pPos[1], pPos[2]) dir := model.Mul4x1(mgl.Vec4{0, 0, 100, 0}) ps.TransformLoc.Dir.Uniform3f(dir[0], dir[1], dir[2]) ps.Data2.BindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0) gl.BeginTransformFeedback(gl.POINTS) gl.DrawArrays(gl.POINTS, 0, ps.NumParticles) gl.EndTransformFeedback() ps.Data1, ps.Data2 = ps.Data2, ps.Data1 ps.VaoRender1, ps.VaoRender2 = ps.VaoRender2, ps.VaoRender1 ps.VaoTff1, ps.VaoTff2 = ps.VaoTff2, ps.VaoTff1 }
func NewGameState(window *sdl.Window, world *World) (gamestate *GameState) { gl.ClearColor(0., 0., 0.4, 0.0) gl.Enable(gl.DEPTH_TEST) bar := tw.NewBar("TweakBar") gamestate = &GameState{ Window: window, Camera: nil, Bar: bar, World: world, Fps: 0, Options: settings.BoolOptions{}, } opt := &gamestate.Options opt.Load() gamestate.Camera = gamestate.World.Player.GetCamera() tw.Define(" GLOBAL help='This example shows how to integrate AntTweakBar with SDL2 and OpenGL.' ") bar.AddVarRO("fps", tw.TYPE_FLOAT, unsafe.Pointer(&gamestate.Fps), "") opt.CreateGui(bar) for i, portal := range gamestate.World.KdTree { ptr := &(portal.(*Portal).Orientation) bar.AddVarRW(fmt.Sprintf("Rotation %d", i), tw.TYPE_QUAT4F, unsafe.Pointer(ptr), "") } //window.GetSize(w, h) w, h := window.GetSize() tw.WindowSize(w, h) return }
func (v *Video) initGL() { if gl.Init() != 0 { panic(sdl.GetError()) } gl.ClearColor(0.0, 0.0, 0.0, 1.0) gl.Enable(gl.CULL_FACE) gl.Enable(gl.DEPTH_TEST) v.prog = createProgram(vertShaderSrcDef, fragShaderSrcDef) posAttrib := v.prog.GetAttribLocation("vPosition") texCoordAttr := v.prog.GetAttribLocation("vTexCoord") v.textureUni = v.prog.GetAttribLocation("texture") v.texture = gl.GenTexture() gl.ActiveTexture(gl.TEXTURE0) v.texture.Bind(gl.TEXTURE_2D) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) v.prog.Use() posAttrib.EnableArray() texCoordAttr.EnableArray() vertVBO := gl.GenBuffer() vertVBO.Bind(gl.ARRAY_BUFFER) verts := []float32{-1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0} gl.BufferData(gl.ARRAY_BUFFER, len(verts)*int(unsafe.Sizeof(verts[0])), &verts[0], gl.STATIC_DRAW) textCoorBuf := gl.GenBuffer() textCoorBuf.Bind(gl.ARRAY_BUFFER) texVerts := []float32{0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0} gl.BufferData(gl.ARRAY_BUFFER, len(texVerts)*int(unsafe.Sizeof(texVerts[0])), &texVerts[0], gl.STATIC_DRAW) posAttrib.AttribPointer(2, gl.FLOAT, false, 0, uintptr(0)) texCoordAttr.AttribPointer(2, gl.FLOAT, false, 0, uintptr(0)) }
func initGL() (err error) { gl.Init() gl.ShadeModel(gl.SMOOTH) gl.ClearColor(0, 0, 0, 0) gl.ClearDepth(1) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) gl.Hint(gl.PERSPECTIVE_CORRECTION_HINT, gl.NICEST) gl.DepthFunc(gl.NEVER) gl.Enable(gl.BLEND) gl.DepthMask(true) //loadShader() return }
func (this *WorldRenderer) render(ww *gamestate.World, options *settings.BoolOptions, viewport Viewport, recursion int, srcPortal *gamestate.Portal) { this.Framebuffer[recursion].Bind() defer this.Framebuffer[recursion].Unbind() gl.Clear(gl.DEPTH_BUFFER_BIT) camera := gamestate.NewCameraFromMat4(this.View) Rot2D := camera.Rotation2D() gl.CullFace(gl.BACK) time := float64(sdl.GetTicks()) / 1000 if options.Wireframe { gl.PolygonMode(gl.FRONT_AND_BACK, gl.LINE) } else { gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL) } if options.Skybox { gl.Disable(gl.DEPTH_TEST) this.SkyboxRenderer.Render(this.Skybox, this.Proj, this.View, this.ClippingPlane_ws, nil) gl.Enable(gl.DEPTH_TEST) } gl.Enable(gl.CULL_FACE) if recursion != 0 { gl.Enable(gl.CLIP_DISTANCE0) defer gl.Disable(gl.CLIP_DISTANCE0) } for _, entity := range ww.ExampleObjects { this.MeshRenderer.Render(entity, this.Proj, this.View, this.ClippingPlane_ws, nil) } gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) gl.Disable(gl.CULL_FACE) if options.WorldRender { this.HeightMapRenderer.Render(ww.HeightMap, this.Proj, this.View, this.ClippingPlane_ws, nil) } PlayerPos := ww.Player.Position() ww.Water.Height = PlayerPos[2] - 15 if options.WaterRender { this.WaterRendererA.Render(ww.Water, this.Proj, this.View, this.ClippingPlane_ws, WaterRenderUniforms{time, PlayerPos}) } if options.WaterNormals { this.WaterRendererB.Render(ww.Water, this.Proj, this.View, this.ClippingPlane_ws, WaterRenderUniforms{time, PlayerPos}) } gl.Disable(gl.CULL_FACE) gl.Disable(gl.BLEND) if options.TreeRender { this.TreeRenderer.Render(ww.Trees, this.Proj, this.View, this.ClippingPlane_ws, Rot2D) } gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE) if options.ParticleRender { this.ParticleSystem.Render(this.Proj, this.View, this.ClippingPlane_ws) } gl.Disable(gl.BLEND) boxVertices := (*gamestate.TriangleMesh)(gamestate.QuadMesh()).MakeBoxVertices() pv := this.Proj.Mul4(this.View) // calculating nearest portal pos4f := this.View.Inv().Mul4x1(mgl.Vec4{0, 0, 0, 1}) nearestPortal := ww.NearestPortal(pos4f) // draw all portals except the nearest and the portal that we are looking throug for _, portal := range ww.Portals { // do not draw the nearest portal or the portal behind the source portal if available if (nearestPortal != portal) && (srcPortal == nil || srcPortal.Target != portal) { gl.Enable(gl.DEPTH_CLAMP) additionalUniforms := map[string]int{"Image": 7} this.PortalRenderer.Render(portal, this.Proj, this.View, this.ClippingPlane_ws, additionalUniforms) } } gl.Disable(gl.BLEND) gl.Disable(gl.CULL_FACE) if options.DebugLines { if options.DepthTestDebugLines { gl.Disable(gl.DEPTH_TEST) } this.DebugRenderer.Render(this.Proj, this.View) gl.Enable(gl.DEPTH_TEST) } // draw if recursion < this.MaxRecursion { portal := nearestPortal pos := portal.Position rotation := portal.Orientation.Mat4() Model := mgl.Translate3D(pos[0], pos[1], pos[2]).Mul4(rotation) pvm := pv.Mul4(Model) meshMin := mgl.Vec4{math.MaxFloat32, math.MaxFloat32, math.MaxFloat32, math.MaxFloat32} meshMax := mgl.Vec4{-math.MaxFloat32, -math.MaxFloat32, -math.MaxFloat32, -math.MaxFloat32} for _, v := range boxVertices { v = pvm.Mul4x1(v) v = v.Mul(1 / v[3]) meshMin = gamestate.Min(meshMin, v) meshMax = gamestate.Max(meshMax, v) } // at least partially visible if -1 < meshMax[0] && meshMin[0] < 1 && -1 < meshMax[1] && meshMin[1] < 1 && -1 < meshMax[2] && meshMin[2] < 1 { p1x, p1y := viewport.ToPixel(meshMin.Vec2()) p2x, p2y := viewport.ToPixel(meshMax.Vec2()) pw, ph := p2x-p1x, p2y-p1y // do scissoring only when all vertices are in front of the camera scissor := meshMax[2] < 1 scissor = scissor && (p1x != 0 || p1y != 0 || pw != viewport.W-1 || ph != viewport.H-1) if scissor { gl.Enable(gl.SCISSOR_TEST) gl.Scissor(p1x, p1y, pw, ph) } // omit rendering when portal is not in frustum at all // calculation View matrix that shows the target portal from the same angle as view shows the source portal //pos2 := portal.Target.Position Model2 := portal.Target.Model() // model matrix, so that portal 1 in camera 1 looks identical to portal 2 in camera oldView := this.View this.View = this.View.Mul4(Model).Mul4(Model2.Inv()) normal_os := portal.Target.Normal normal_ws := Model.Mul4x1(normal_os) view_dir := helpers.HomogenDiff(portal.Position, camera.Position) sign := view_dir.Dot(normal_ws) oldClippingPlane := this.ClippingPlane_ws this.ClippingPlane_ws = portal.Target.ClippingPlane(sign > 0) this.render(ww, options, viewport, recursion+1, nearestPortal) this.ClippingPlane_ws = oldClippingPlane this.View = oldView gl.ActiveTexture(gl.TEXTURE0) this.Framebuffer[recursion+1].RenderTexture.Bind(gl.TEXTURE_RECTANGLE) if scissor { //gl.Scissor(0, 0, w, h) gl.Disable(gl.SCISSOR_TEST) } this.Framebuffer[recursion].Bind() gl.Enable(gl.DEPTH_CLAMP) additionalUniforms := map[string]int{"Image": 0} this.PortalRenderer.Render(nearestPortal, this.Proj, this.View, this.ClippingPlane_ws, additionalUniforms) } } }
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 NewTextures(heightMap *gamestate.HeightMap) *Textures { textures := make([]gl.Texture, 10) gl.GenTextures(textures) gl.ActiveTexture(gl.TEXTURE0 + constants.TextureGround) textures[1].Bind(gl.TEXTURE_2D) helpers.LoadTexture2DWatched("textures/GravelCobbleS.jpg") gl.GenerateMipmap(gl.TEXTURE_2D) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_R, gl.REPEAT) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT) gl.ActiveTexture(gl.TEXTURE0 + constants.TextureCliffs) textures[2].Bind(gl.TEXTURE_2D) helpers.LoadTexture2DWatched("textures/Cliffs0149_18_S.png") gl.GenerateMipmap(gl.TEXTURE_2D) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_R, gl.REPEAT) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT) gl.ActiveTexture(gl.TEXTURE0 + constants.TextureColorBand) textures[3].Bind(gl.TEXTURE_1D) helpers.LoadTexture1DWatched("textures/gradient.png") gl.TexParameteri(gl.TEXTURE_1D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_1D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.ActiveTexture(gl.TEXTURE0 + constants.TextureHeightMap) textures[4].Bind(gl.TEXTURE_2D) gl.TexImage2D(gl.TEXTURE_2D, 0, gl.R16, heightMap.W, heightMap.H, 0, gl.RED, gl.FLOAT, heightMap.TexturePixels()) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT) gl.ActiveTexture(gl.TEXTURE0 + constants.TextureTree) textures[5].Bind(gl.TEXTURE_2D) helpers.LoadTexture2DWatched("textures/palme.png") gl.GenerateMipmap(gl.TEXTURE_2D) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) gl.ActiveTexture(gl.TEXTURE0 + constants.TextureFireBall) textures[6].Bind(gl.TEXTURE_2D) helpers.LoadTexture2DWatched("textures/fireball.png") gl.GenerateMipmap(gl.TEXTURE_2D) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) gl.ActiveTexture(gl.TEXTURE0 + constants.TextureSkybox) textures[7].Bind(gl.TEXTURE_CUBE_MAP) helpers.LoadTextureCubeWatched("textures/Above_The_Sea.jpg") gl.GenerateMipmap(gl.TEXTURE_CUBE_MAP) gl.TexParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR) gl.TexParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR) //gl.TexParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE) gl.TexParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) gl.TexParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) gl.Enable(gl.TEXTURE_CUBE_MAP_SEAMLESS) ttf.Init() defer ttf.Quit() font, _ := ttf.OpenFont("fonts/Symbola.ttf", 64) color := sdl.Color{255, 255, 255, 255} surface, _ := font.RenderUTF8_Blended("Bla", color) defer surface.Free() gl.ActiveTexture(gl.TEXTURE0 + constants.TextureFont) textures[8].Bind(gl.TEXTURE_2D) gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int(surface.W), int(surface.H), 0, gl.RGBA, gl.UNSIGNED_BYTE, uintptr(surface.Data())) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.ActiveTexture(gl.TEXTURE0) return &Textures{textures} }