gl01/internal/render/render_world.go.old

120 lines
3.6 KiB
Go
Raw Normal View History

2022-01-20 21:58:50 +08:00
package render
import (
"time"
"unsafe"
"github.com/Edgaru089/gl01/internal/asset"
"github.com/Edgaru089/gl01/internal/util/itype"
"github.com/Edgaru089/gl01/internal/world"
"github.com/go-gl/gl/all-core/gl"
"github.com/go-gl/mathgl/mgl32"
)
// WorldRenderer holds texture/shader resource and viewport
// information for world rendering.
type WorldRenderer struct {
shader *Shader
texture *Texture
vao, vbo uint32
vbolen int
vertex []world.Vertex
// for testing!
initTime time.Time
}
// The default WorldRenderer.
var DefaultWorldRenderer WorldRenderer
// Init initializes the WorldRenderer.
func (r *WorldRenderer) Init(w *world.World) (err error) {
r.shader, err = NewShader(asset.WorldShaderVert, asset.WorldShaderFrag)
if err != nil {
return err
}
asset.InitWorldTextureAtlas()
r.texture = NewTextureRGBA(asset.WorldTextureAtlas.Image)
r.shader.SetUniformTexture("tex", r.texture)
r.shader.SetUniformMat4("model", mgl32.Ident4())
// and view and projection uniforms not yet set
gl.BindFragDataLocation(r.shader.Handle(), 0, gl.Str("outputColor\x00"))
gl.GenVertexArrays(1, &r.vao)
gl.BindVertexArray(r.vao)
gl.GenBuffers(1, &r.vbo)
gl.BindBuffer(gl.ARRAY_BUFFER, r.vbo)
gensync := make(chan []world.Vertex, len(w.Chunks))
for _, c := range w.Chunks {
chunk := c
go func() {
arr := chunk.AppendVertex([]world.Vertex{})
gensync <- arr
}()
}
for range w.Chunks {
r.vertex = append(r.vertex, (<-gensync)...)
}
close(gensync)
gl.BufferData(gl.ARRAY_BUFFER, int(unsafe.Sizeof(world.Vertex{}))*len(r.vertex), gl.Ptr(r.vertex), gl.DYNAMIC_DRAW)
vertAttrib := uint32(gl.GetAttribLocation(r.shader.Handle(), gl.Str("vert\x00")))
gl.VertexAttribPointer(vertAttrib, 3, gl.FLOAT, false, int32(unsafe.Sizeof(world.Vertex{})), gl.PtrOffset(int(unsafe.Offsetof(world.Vertex{}.World))))
normalAttrib := uint32(gl.GetAttribLocation(r.shader.Handle(), gl.Str("normal\x00")))
gl.VertexAttribPointer(normalAttrib, 3, gl.FLOAT, false, int32(unsafe.Sizeof(world.Vertex{})), gl.PtrOffset(int(unsafe.Offsetof(world.Vertex{}.Normal))))
texCoordAttrib := uint32(gl.GetAttribLocation(r.shader.Handle(), gl.Str("vertTexCoord\x00")))
gl.VertexAttribPointer(texCoordAttrib, 2, gl.FLOAT, false, int32(unsafe.Sizeof(world.Vertex{})), gl.PtrOffset(int(unsafe.Offsetof(world.Vertex{}.Texture))))
lightAttrib := uint32(gl.GetAttribLocation(r.shader.Handle(), gl.Str("light\x00")))
gl.VertexAttribPointer(lightAttrib, 1, gl.FLOAT, false, int32(unsafe.Sizeof(world.Vertex{})), gl.PtrOffset(int(unsafe.Offsetof(world.Vertex{}.Light))))
gl.EnableVertexAttribArray(vertAttrib)
gl.EnableVertexAttribArray(normalAttrib)
gl.EnableVertexAttribArray(texCoordAttrib)
gl.EnableVertexAttribArray(lightAttrib)
w.EnableVertexArrayAttrib(vertAttrib)
w.EnableVertexArrayAttrib(normalAttrib)
w.EnableVertexArrayAttrib(texCoordAttrib)
w.EnableVertexArrayAttrib(lightAttrib)
gl.Enable(gl.CULL_FACE)
gl.Enable(gl.DEPTH_TEST)
gl.DepthFunc(gl.LESS)
r.initTime = time.Now()
return nil
}
func (r *WorldRenderer) Render(world *world.World, view *View) {
r.shader.UseProgram()
r.shader.BindTextures()
r.shader.SetUniformMat4("view", view.view)
r.shader.SetUniformMat4("projection", mgl32.Perspective(view.fovy, view.aspect, 0.1, 200))
r.shader.SetUniformVec3f("sun", itype.Vec3f{-0.2, 1, 0.8}.Normalize())
// for testing!
//model := mgl32.HomogRotate3D(float32(time.Since(r.initTime).Seconds()), mgl32.Vec3{0, 1, 0})
//r.shader.SetUniformMat4("model", model)
//r.shader.SetUniformMat4("view", r.view)
gl.BindVertexArray(r.vao)
gl.BindBuffer(gl.ARRAY_BUFFER, r.vbo)
gl.DrawArrays(gl.TRIANGLES, 0, int32(len(r.vertex)))
world.Render()
//world.Chunk(0, 0).Render()
}