opengl-deferred/main.go

213 lines
5.3 KiB
Go

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...")
}