semi-transparent water rendering (TODO)
This commit is contained in:
@ -36,7 +36,8 @@ type BlockAppearance struct {
|
||||
data itype.Dataset,
|
||||
world *World,
|
||||
vertexArray []Vertex,
|
||||
) []Vertex
|
||||
vertexArrayWater []Vertex,
|
||||
) (verts []Vertex, waters []Vertex)
|
||||
}
|
||||
|
||||
// BlockBehaviour describes a kind of block of the same Major ID.
|
||||
|
@ -10,7 +10,7 @@ type WaterBehaviour struct{}
|
||||
func (WaterBehaviour) Static() bool { return false }
|
||||
func (WaterBehaviour) RequireDataset() bool { return false }
|
||||
func (WaterBehaviour) RequireBlockUpdate() bool { return false }
|
||||
func (b WaterBehaviour) Appearance(position itype.Vec3i, aux int, data itype.Dataset, w *world.World) world.BlockAppearance {
|
||||
func (WaterBehaviour) Appearance(position itype.Vec3i, aux int, data itype.Dataset, w *world.World) world.BlockAppearance {
|
||||
return world.BlockAppearance{
|
||||
Name: "water",
|
||||
Transparent: true,
|
||||
@ -22,13 +22,13 @@ func (b WaterBehaviour) Appearance(position itype.Vec3i, aux int, data itype.Dat
|
||||
aux int,
|
||||
data itype.Dataset,
|
||||
w *world.World,
|
||||
vertexArray []world.Vertex) []world.Vertex {
|
||||
vertexArray []world.Vertex, vertsWater []world.Vertex) (verts, waters []world.Vertex) {
|
||||
|
||||
if block := w.Block(position.Addv(0, 1, 0)); block.Id != Water {
|
||||
return appendFace(itype.YPlus, position, "water.png", itype.Vec3f{0, -0.125, 0}, vertexArray)
|
||||
return vertexArray, appendFace(itype.YPlus, position, "water.png", itype.Vec3f{0, -0.125, 0}, vertsWater)
|
||||
}
|
||||
|
||||
return vertexArray
|
||||
return vertexArray, vertsWater
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ type Chunk struct {
|
||||
vao, vbo uint32
|
||||
vbolen int
|
||||
}
|
||||
vertUpdate chan []Vertex
|
||||
vertUpdate chan [2][]Vertex
|
||||
|
||||
world *World
|
||||
}
|
||||
|
@ -34,7 +34,21 @@ func (c *Chunk) InitRender() {
|
||||
gl.EnableVertexAttribArray(2)
|
||||
gl.EnableVertexAttribArray(3)
|
||||
|
||||
c.vertUpdate = make(chan []Vertex, 2)
|
||||
gl.GenVertexArrays(1, &c.water.vao)
|
||||
gl.BindVertexArray(c.water.vao)
|
||||
gl.GenBuffers(1, &c.water.vbo)
|
||||
gl.BindBuffer(gl.ARRAY_BUFFER, c.water.vbo)
|
||||
|
||||
gl.VertexAttribPointer(0, 3, gl.FLOAT, false, int32(unsafe.Sizeof(Vertex{})), gl.PtrOffset(int(unsafe.Offsetof(Vertex{}.World))))
|
||||
gl.VertexAttribPointer(1, 3, gl.FLOAT, false, int32(unsafe.Sizeof(Vertex{})), gl.PtrOffset(int(unsafe.Offsetof(Vertex{}.Normal))))
|
||||
gl.VertexAttribPointer(2, 2, gl.FLOAT, false, int32(unsafe.Sizeof(Vertex{})), gl.PtrOffset(int(unsafe.Offsetof(Vertex{}.Texture))))
|
||||
gl.VertexAttribPointer(3, 1, gl.FLOAT, false, int32(unsafe.Sizeof(Vertex{})), gl.PtrOffset(int(unsafe.Offsetof(Vertex{}.Light))))
|
||||
gl.EnableVertexAttribArray(0)
|
||||
gl.EnableVertexAttribArray(1)
|
||||
gl.EnableVertexAttribArray(2)
|
||||
gl.EnableVertexAttribArray(3)
|
||||
|
||||
c.vertUpdate = make(chan [2][]Vertex, 2)
|
||||
|
||||
c.renderChanged = true
|
||||
}
|
||||
@ -42,6 +56,8 @@ func (c *Chunk) InitRender() {
|
||||
func (c *Chunk) FreeRender() {
|
||||
gl.DeleteVertexArrays(1, &c.vao)
|
||||
gl.DeleteBuffers(1, &c.vbo)
|
||||
gl.DeleteVertexArrays(1, &c.water.vao)
|
||||
gl.DeleteBuffers(1, &c.water.vbo)
|
||||
close(c.vertUpdate)
|
||||
}
|
||||
|
||||
@ -51,6 +67,12 @@ func (c *Chunk) Bind() {
|
||||
gl.BindBuffer(gl.ARRAY_BUFFER, c.vbo)
|
||||
}
|
||||
|
||||
// BindWater binds the semi-transparant layer of the renderer.
|
||||
func (c *Chunk) BindWater() {
|
||||
gl.BindVertexArray(c.water.vao)
|
||||
gl.BindBuffer(gl.ARRAY_BUFFER, c.water.vbo)
|
||||
}
|
||||
|
||||
// a global vertex array for VBO updates
|
||||
//var vertex []Vertex
|
||||
|
||||
@ -59,17 +81,21 @@ func (c *Chunk) updateRender() {
|
||||
if c.renderChanged {
|
||||
go func() {
|
||||
t := time.Now()
|
||||
vert := c.AppendVertex([]Vertex{})
|
||||
vert, vertWater := c.appendVertex([]Vertex{}, []Vertex{})
|
||||
log.Printf("Chunk [%d,%d]: UpdateRender: vertex len of %d*%d = %d in %dms", c.X, c.Z, unsafe.Sizeof(Vertex{}), len(vert), int(unsafe.Sizeof(Vertex{}))*len(vert), time.Since(t).Milliseconds())
|
||||
c.vertUpdate <- vert
|
||||
c.vertUpdate <- [2][]Vertex{vert, vertWater}
|
||||
}()
|
||||
c.renderChanged = false
|
||||
}
|
||||
|
||||
select {
|
||||
case vert := <-c.vertUpdate:
|
||||
gl.BufferData(gl.ARRAY_BUFFER, int(unsafe.Sizeof(Vertex{}))*len(vert), gl.Ptr(vert), gl.DYNAMIC_DRAW)
|
||||
c.vbolen = len(vert)
|
||||
gl.BindBuffer(gl.ARRAY_BUFFER, c.vbo)
|
||||
gl.BufferData(gl.ARRAY_BUFFER, int(unsafe.Sizeof(Vertex{}))*len(vert[0]), gl.Ptr(vert[0]), gl.DYNAMIC_DRAW)
|
||||
gl.BindBuffer(gl.ARRAY_BUFFER, c.water.vbo)
|
||||
gl.BufferData(gl.ARRAY_BUFFER, int(unsafe.Sizeof(Vertex{}))*len(vert[1]), gl.Ptr(vert[1]), gl.DYNAMIC_DRAW)
|
||||
c.vbolen = len(vert[0])
|
||||
c.water.vbolen = len(vert[1])
|
||||
default: // do nothing
|
||||
}
|
||||
}
|
||||
@ -107,13 +133,23 @@ func (c *Chunk) Render() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Bind()
|
||||
c.updateRender()
|
||||
c.Bind()
|
||||
gl.DrawArrays(gl.TRIANGLES, 0, int32(c.vbolen))
|
||||
}
|
||||
|
||||
// AppendVertex appends the chunk's global vertex into the array.
|
||||
func (c *Chunk) AppendVertex(arr []Vertex) []Vertex {
|
||||
func (c *Chunk) RenderWater() {
|
||||
if !c.checkView(io.ViewPos, io.ViewDir) || !c.checkView(io.RenderPos, io.RenderDir) {
|
||||
return
|
||||
}
|
||||
|
||||
c.updateRender()
|
||||
c.BindWater()
|
||||
gl.DrawArrays(gl.TRIANGLES, 0, int32(c.water.vbolen))
|
||||
}
|
||||
|
||||
// appendVertex appends the chunk's global vertex into the array.
|
||||
func (c *Chunk) appendVertex(arr, arrwater []Vertex) (fin, finwater []Vertex) {
|
||||
off := itype.Vec3i{
|
||||
c.X * ChunkSizeX,
|
||||
0,
|
||||
@ -151,14 +187,14 @@ func (c *Chunk) AppendVertex(arr []Vertex) []Vertex {
|
||||
arr = c.appendFace(itype.ZPlus, itype.Vec3i{i, j, k}, app.Name+"_z+.png", arr)
|
||||
arr = c.appendFace(itype.ZMinus, itype.Vec3i{i, j, k}, app.Name+"_z-.png", arr)
|
||||
case CustomRendering:
|
||||
arr = app.CustomRenderAppend(off.Addv(i, j, k), int(c.Aux[i][j][k]), nil, c.world, arr)
|
||||
arr, arrwater = app.CustomRenderAppend(off.Addv(i, j, k), int(c.Aux[i][j][k]), nil, c.world, arr, arrwater)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return arr
|
||||
return arr, arrwater
|
||||
}
|
||||
|
||||
func (c *Chunk) appendFace(face itype.Direction, pos itype.Vec3i, texname string, arr []Vertex) []Vertex {
|
||||
|
@ -145,3 +145,11 @@ func (w *World) Render() {
|
||||
c.Render()
|
||||
}
|
||||
}
|
||||
|
||||
// RenderWater calls DrawArrays drawing the semi-transparant layer of the world.
|
||||
func (w *World) RenderWater() {
|
||||
for _, c := range w.Chunks {
|
||||
c.RenderWater()
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user