package main import ( "fmt" "runtime" "git.tek.govt.hu/dowerx/opengl-deferred/types/gbuffer" "git.tek.govt.hu/dowerx/opengl-deferred/types/geometry" "git.tek.govt.hu/dowerx/opengl-deferred/types/light" "git.tek.govt.hu/dowerx/opengl-deferred/types/shader" "git.tek.govt.hu/dowerx/opengl-deferred/types/texture" "git.tek.govt.hu/dowerx/opengl-deferred/utils/assetmanager" "git.tek.govt.hu/dowerx/opengl-deferred/utils/fpscontrols" "github.com/go-gl/gl/v4.6-core/gl" "github.com/go-gl/glfw/v3.3/glfw" "github.com/go-gl/mathgl/mgl32" ) const ( WIDTH = 1600 HEIGHT = 900 TITLE = "opengl-deferred" FOV = 45.0 ) func main() { // init glfw runtime.LockOSThread() if err := glfw.Init(); err != nil { panic(err) } defer glfw.Terminate() glfw.WindowHint(glfw.Resizable, glfw.False) glfw.WindowHint(glfw.ContextVersionMajor, 4) glfw.WindowHint(glfw.ContextVersionMinor, 6) glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True) window, err := glfw.CreateWindow(WIDTH, HEIGHT, TITLE, nil, nil) if err != nil { panic(err) } window.MakeContextCurrent() // init gl if err := gl.Init(); err != nil { panic(err) } gl.Enable(gl.CULL_FACE) gl.DepthFunc(gl.LESS) gl.ClearColor(0, 0, 0, 1) fmt.Println("OpenGL version:", gl.GoStr(gl.GetString(gl.VERSION))) // load assets assetManager := assetmanager.Get() defer assetManager.Delete() // shader tmpShader, err := shader.FromFiles("assets/shader/deferred/deferred.vs", "assets/shader/deferred/deferred.fs") if err != nil { panic(err) } assetManager.Add("deferred", tmpShader) tmpShader, err = shader.FromFiles("assets/shader/pbr/pbr.vs", "assets/shader/pbr/pbr.fs") if err != nil { panic(err) } assetManager.Add("pbr", tmpShader) tmpShader, err = shader.FromFiles("assets/shader/screen/screen.vs", "assets/shader/screen/screen.fs") if err != nil { panic(err) } assetManager.Add("screen", tmpShader) deferredShader := assetManager.Shadres["deferred"] screenShader := assetManager.Shadres["pbr"] // geometry tmpGeometry, err := geometry.LoadOBJ("assets/geometries/20.obj") if err != nil { panic(err) } assetManager.Add("teapot", tmpGeometry) // tmpGeometry, err = geometry.LoadOBJ("assets/geometries/plane.obj") // if err != nil { // panic(err) // } // assetManager.Add("plane", tmpGeometry) screen, err := geometry.Screen() if err != nil { panic(err) } defer screen.Delete() // textures tmpTexture, err := texture.Load("assets/textures/TCom_Pavement_PaintedConcrete3_512_albedo.tif") if err != nil { panic(err) } assetManager.Add("albedo", tmpTexture) tmpTexture, err = texture.Load("assets/textures/TCom_Pavement_PaintedConcrete3_512_normal.tif") if err != nil { panic(err) } assetManager.Add("normal", tmpTexture) tmpTexture, err = texture.Load("assets/textures/TCom_Pavement_PaintedConcrete3_512_roughness.tif") if err != nil { panic(err) } assetManager.Add("roughness", tmpTexture) tmpTexture, err = texture.Load("assets/textures/white.png") if err != nil { panic(err) } assetManager.Add("white", tmpTexture) tmpTexture, err = texture.Load("assets/textures/black.png") if err != nil { panic(err) } assetManager.Add("black", tmpTexture) // lights lights := []light.Light{ {Color: [3]float32{1, 1, 1}, Position: mgl32.Vec3{0, 10, 0}, Intensity: 40, Type: light.POINT}, {Color: [3]float32{1, 0, 0}, Position: mgl32.Vec3{5, 5, 5}, Intensity: 30, Type: light.POINT}, {Color: [3]float32{0, 0, 1}, Position: mgl32.Vec3{-5, 5, -5}, Intensity: 30, Type: light.POINT}, } // gbuffer gbuff, err := gbuffer.New(WIDTH, HEIGHT) if err != nil { panic(err) } defer gbuff.Delete() gbuff.Bind() // transformations projection := mgl32.Perspective(mgl32.DegToRad(FOV), float32(WIDTH)/HEIGHT, 0.1, 1000) model := mgl32.Ident4() controls := fpscontrols.Get(10, 10, mgl32.Vec3{0, 0, -10}, mgl32.Vec2{0, 0}, window) for !window.ShouldClose() { glfw.PollEvents() controls.Update() // first pass gl.Enable(gl.DEPTH_TEST) gbuff.Bind() gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) assetManager.Textures["albedo"].Bind(gl.TEXTURE0) assetManager.Textures["normal"].Bind(gl.TEXTURE1) assetManager.Textures["roughness"].Bind(gl.TEXTURE2) assetManager.Textures["roughness"].Bind(gl.TEXTURE3) assetManager.Textures["roughness"].Bind(gl.TEXTURE4) // transfer uniforms deferredShader.Use() deferredShader.Mat4("projection", projection) deferredShader.Mat4("view", controls.View()) deferredShader.Mat4("model", model) deferredShader.Int("s_albedo", 0) deferredShader.Int("s_normal", 1) deferredShader.Int("s_specular", 2) deferredShader.Int("s_roughness", 3) deferredShader.Int("s_metalic", 4) for _, g := range assetManager.Geometries { g.Draw() } // second pass gl.Disable(gl.DEPTH_TEST) gl.BindFramebuffer(gl.FRAMEBUFFER, 0) gl.Clear(gl.COLOR_BUFFER_BIT) gbuff.BindTextures() screenShader.Use() screenShader.Int("s_albedo", 0) screenShader.Int("s_depth", 1) screenShader.Int("s_normal", 2) screenShader.Int("s_material", 3) screenShader.Int("s_position", 4) pos := controls.Position() screenShader.Vec3("view_pos", &pos[0]) for _, light := range lights { screenShader.Light(&light) } screen.Draw() window.SwapBuffers() } defer fmt.Println("exiting...") }