diff --git a/internal/asset/shader.go b/internal/asset/shader.go index ed4e8bf..8a6ed21 100644 --- a/internal/asset/shader.go +++ b/internal/asset/shader.go @@ -2,23 +2,27 @@ package asset import _ "embed" -//go:embed shader/world.frag -var WorldShaderFrag string +var ( + //go:embed shader/world/output.frag + WorldShaderFrag string + //go:embed shader/world/output.vert + WorldShaderVert string -//go:embed shader/world.vert -var WorldShaderVert string + //go:embed shader/world/shadowmap.frag + WorldShaderShadowmapFrag string + //go:embed shader/world/shadowmap.vert + WorldShaderShadowmapVert string -//go:embed shader/world.shadowmap.frag -var WorldShaderShadowmapFrag string + //go:embed shader/world/geometry.frag + WorldShaderGeometryFrag string + //go:embed shader/world/geometry.vert + WorldShaderGeometryVert string -//go:embed shader/world.shadowmap.vert -var WorldShaderShadowmapVert string - -//go:embed shader/world.geometry.frag -var WorldShaderGeometryFrag string - -//go:embed shader/world.geometry.vert -var WorldShaderGeometryVert string + //go:embed shader/world/water.frag + WorldShaderWaterFrag string + //go:embed shader/world/water.vert + WorldShaderWaterVert string +) //go:embed shader/framewire.frag var FramewireShaderFrag string diff --git a/internal/asset/shader/world.geometry.frag b/internal/asset/shader/world/geometry.frag similarity index 100% rename from internal/asset/shader/world.geometry.frag rename to internal/asset/shader/world/geometry.frag diff --git a/internal/asset/shader/world.geometry.vert b/internal/asset/shader/world/geometry.vert similarity index 100% rename from internal/asset/shader/world.geometry.vert rename to internal/asset/shader/world/geometry.vert diff --git a/internal/asset/shader/world.frag b/internal/asset/shader/world/output.frag similarity index 97% rename from internal/asset/shader/world.frag rename to internal/asset/shader/world/output.frag index 3c36d34..a734769 100644 --- a/internal/asset/shader/world.frag +++ b/internal/asset/shader/world/output.frag @@ -24,7 +24,7 @@ out vec4 outputColor; const float gamma = 2.2; -const float ambient = 0.3, specularStrength = 0.5, specularShininess = 32; +const float ambient = 0.3, specularStrength = 0.08, specularShininess = 8; const float fogDensity = .00003; diff --git a/internal/asset/shader/world.vert b/internal/asset/shader/world/output.vert similarity index 100% rename from internal/asset/shader/world.vert rename to internal/asset/shader/world/output.vert diff --git a/internal/asset/shader/world.shadowmap.frag b/internal/asset/shader/world/shadowmap.frag similarity index 100% rename from internal/asset/shader/world.shadowmap.frag rename to internal/asset/shader/world/shadowmap.frag diff --git a/internal/asset/shader/world.shadowmap.vert b/internal/asset/shader/world/shadowmap.vert similarity index 100% rename from internal/asset/shader/world.shadowmap.vert rename to internal/asset/shader/world/shadowmap.vert diff --git a/internal/asset/shader/world/water.frag b/internal/asset/shader/world/water.frag new file mode 100644 index 0000000..d8b76b6 --- /dev/null +++ b/internal/asset/shader/world/water.frag @@ -0,0 +1,93 @@ +#version 330 + +uniform sampler2D tex; +uniform sampler2D shadowmap; +uniform vec3 viewPos; +uniform vec3 sun; +uniform vec4 fogColor; + +uniform float alpha; // Alpha of the semi-transparant layer + +// Fragment information +in vec4 fragPos; +in vec4 fragPosLightspace; +in vec3 fragNormal; +in vec2 fragTexCoord; +vec4 fragColor; + +out vec4 outputColor; + + +const float gamma = 2.2; + +const float ambient = 0.3, specularStrength = 1.6, specularShininess = 128; +const float fogDensity = .00003; + + +float finalpha; +float light; +vec4 texpixel, color; +void lightSun(); +float lightSunShadow(); +void lightPoint(int i); + + +void main() { + + fragColor = vec4(pow(texture(tex, fragTexCoord).rgb, vec3(gamma)), 1.0f); + + finalpha = alpha; + light = ambient; + + lightSun(); + + color += vec4(fragColor.rgb * light, 0.0f); + color.a = fragColor.a; + color.rgb = pow(color.rgb, vec3(1.0/gamma)); + + float z = gl_FragCoord.z / gl_FragCoord.w; + float fog = clamp(exp(-fogDensity * z * z), 0.2, 1); + + outputColor = mix(fogColor, color, fog) * finalpha; +} + +void lightSun() { + /* Diffuse */ + vec3 lightDir = sun; + float diffuse = max(dot(fragNormal, lightDir), 0.0f); + + /* Specular */ + vec3 viewDir = normalize(viewPos - fragPos.xyz); + vec3 reflectDir = reflect(-lightDir, fragNormal); + float specular = specularStrength * pow(max(dot(viewDir, reflectDir), 0.0), specularShininess); + if (specular > 1.0f) { + finalpha = min(finalpha + specular - 1.0f, 1.0f); + } + + float shadow = lightSunShadow(); + light += diffuse * shadow; + color += vec4(vec3(specular), 0.0f) * shadow; + finalpha = min(finalpha + 0.1f * shadow, 1.0f); +} + +float lightSunShadow() { + /* Shadow */ + float bias = max(0.0013 * (1.0 - dot(fragNormal, sun)), 0.0001); + vec3 projCoords = fragPosLightspace.xyz / fragPosLightspace.w; + projCoords = projCoords*0.5 + 0.5; + float closestDepth = texture(shadowmap, projCoords.xy).r; + float currentDepth = projCoords.z; + float shadow = 0; + + if (currentDepth > 1.0f || currentDepth < 0.0f) + return 1.0f; + + //vec2 texelSize = clamp((currentDepth+bias-closestDepth)*100.0f, 0.05f, 1.5f) / textureSize(shadowmap, 0); + vec2 texelSize = 0.4 / textureSize(shadowmap, 0); + for (int x=-4; x<=4; ++x) + for (int y=-4; y<=4; ++y) { + float pcfDepth = texture(shadowmap, projCoords.xy + vec2(x,y)*texelSize).r; + shadow += currentDepth-bias < pcfDepth ? 1.0f : 0.0f; + } + return min(shadow/81.0f, 1.0f); +} diff --git a/internal/asset/shader/world/water.vert b/internal/asset/shader/world/water.vert new file mode 100644 index 0000000..f6f917b --- /dev/null +++ b/internal/asset/shader/world/water.vert @@ -0,0 +1,26 @@ +#version 330 + +uniform mat4 projection; +uniform mat4 view; +uniform mat4 model; +uniform mat4 lightspace; + +layout (location = 0) in vec3 vert; +layout (location = 1) in vec3 normal; +layout (location = 2) in vec2 texCoord; +layout (location = 4) in float light; + +out vec4 fragPos; +out vec4 fragPosLightspace; +out vec3 fragNormal; +out vec2 fragTexCoord; + + +void main() { + fragTexCoord = texCoord; + fragPos = model * vec4(vert, 1); + fragPosLightspace = lightspace * fragPos; + fragNormal = normal; + gl_Position = projection * view * fragPos; +} + diff --git a/internal/entity/.physics.go.swp b/internal/entity/.physics.go.swp new file mode 100644 index 0000000..594ecab Binary files /dev/null and b/internal/entity/.physics.go.swp differ diff --git a/internal/entity/physics.go b/internal/entity/physics.go index 07518d7..794001d 100644 --- a/internal/entity/physics.go +++ b/internal/entity/physics.go @@ -45,35 +45,6 @@ func (e *Entity) boxHitpoints(points []itype.Vec3d, hitbox itype.Boxd) []itype.V base.Add(itype.Vec3d{box.SizeX, 0, box.SizeZ}), base.Add(itype.Vec3d{box.SizeX, box.SizeY, box.SizeZ}), ) - /* - // add the surface points - // X+ and X- - for y := base[1] + HitpointMeshLen; y < base[1]+hitbox[1]; y += HitpointMeshLen { - for z := base[2] + HitpointMeshLen; z < base[2]+hitbox[2]; z += HitpointMeshLen { - points = append(points, - base.Addv(0, y, z), - base.Addv(box.SizeX, y, z), - ) - } - } - // Y+ and Y- - for x := base[0] + HitpointMeshLen; x < base[0]+hitbox[0]; x += HitpointMeshLen { - for z := base[2] + HitpointMeshLen; z < base[2]+hitbox[2]; z += HitpointMeshLen { - points = append(points, - base.Addv(x, 0, z), - base.Addv(x, box.SizeY, z), - ) - } - } - // Z+ and Z- - for x := base[0] + HitpointMeshLen; x < base[0]+hitbox[0]; x += HitpointMeshLen { - for y := base[1] + HitpointMeshLen; y < base[1]+hitbox[1]; y += HitpointMeshLen { - points = append(points, - base.Addv(x, y, 0), - base.Addv(x, y, box.SizeZ), - ) - } - }*/ return points } @@ -89,6 +60,7 @@ func pointStuck(point itype.Vec3d, w *world.World) bool { point.Floor(), block.Aux, block.Dataset, + w, ).Hitbox.Offset(blockid.ToFloat64()).Contains(point) } @@ -123,7 +95,7 @@ func (e *Entity) moveX(delta float64, hitbox itype.Boxd, w *world.World) { if block.Id == 0 { deltaDone = delta } else { // block.Id!=0 - app := world.GetBlockAppearance(blockid, block.Id, block.Aux, block.Dataset) + app := world.GetBlockAppearance(blockid, block.Id, block.Aux, block.Dataset, w) blockBox := app.Hitbox.Offset(blockid.ToFloat64()) if !app.NotSolid && blockBox.Contains(dest) { // Hit! hit = true @@ -176,7 +148,7 @@ func (e *Entity) moveY(delta float64, hitbox itype.Boxd, w *world.World) { if block.Id == 0 { deltaDone = delta } else { // block.Id!=0 - app := world.GetBlockAppearance(blockid, block.Id, block.Aux, block.Dataset) + app := world.GetBlockAppearance(blockid, block.Id, block.Aux, block.Dataset, w) blockBox := app.Hitbox.Offset(blockid.ToFloat64()) if !app.NotSolid && blockBox.Contains(dest) { // Hit! hit = true @@ -240,7 +212,7 @@ func (e *Entity) moveZ(delta float64, hitbox itype.Boxd, w *world.World) { if block.Id == 0 { deltaDone = delta } else { // block.Id!=0 - app := world.GetBlockAppearance(blockid, block.Id, block.Aux, block.Dataset) + app := world.GetBlockAppearance(blockid, block.Id, block.Aux, block.Dataset, w) blockBox := app.Hitbox.Offset(blockid.ToFloat64()) if !app.NotSolid && blockBox.Contains(dest) { // Hit! hit = true diff --git a/internal/game/logic.go b/internal/game/logic.go index db60f8d..2f3c349 100644 --- a/internal/game/logic.go +++ b/internal/game/logic.go @@ -47,8 +47,8 @@ func (g *Game) Init(win *glfw.Window) { var seed int64 = time.Now().Unix() gensync := make(chan struct{}) gensynccnt := 0 - for i := -8; i <= 8; i++ { - for j := -8; j <= 8; j++ { + for i := -4; i <= 4; i++ { + for j := -4; j <= 4; j++ { c := &world.Chunk{} g.world.SetChunk(i, j, c) go func() { diff --git a/internal/render/render_world.go b/internal/render/render_world.go index d225c24..3dd5098 100644 --- a/internal/render/render_world.go +++ b/internal/render/render_world.go @@ -33,6 +33,11 @@ type WorldRenderer struct { shader *Shader // Geometry pass shaders. } + water struct { + fbo uint32 + shader *Shader + } + shader *Shader // Deffered lighting pass shaders texture *Texture // World texture atlas } @@ -55,16 +60,23 @@ func (r *WorldRenderer) Init(w *world.World) (err error) { if err != nil { return err } + r.water.shader, err = NewShader(asset.WorldShaderWaterVert, asset.WorldShaderWaterFrag) + if err != nil { + return err + } asset.InitWorldTextureAtlas() r.texture = NewTextureRGBA(asset.WorldTextureAtlas.Image) r.texture.GenerateMipMap() r.gbuffer.shader.SetUniformTexture("tex", r.texture) + r.water.shader.SetUniformTexture("tex", r.texture) r.depthmap.shader.SetUniformMat4("model", mgl32.Ident4()) r.gbuffer.shader.SetUniformMat4("model", mgl32.Ident4()) + r.water.shader.SetUniformMat4("model", mgl32.Ident4()) // and view and projection uniforms not yet set gl.BindFragDataLocation(r.shader.Handle(), 0, gl.Str("outputColor\x00")) + gl.BindFragDataLocation(r.water.shader.Handle(), 0, gl.Str("outputColor\x00")) // generate the depthmap and depthmap FBO gl.GenFramebuffers(1, &r.depthmap.fbo) @@ -84,6 +96,7 @@ func (r *WorldRenderer) Init(w *world.World) (err error) { gl.ReadBuffer(gl.NONE) // attach the shadowmap to the shader r.shader.SetUniformTextureHandle("shadowmap", r.depthmap.tex) + r.water.shader.SetUniformTextureHandle("shadowmap", r.depthmap.tex) // generate G-buffer and friends gl.GenFramebuffers(1, &r.gbuffer.fbo) @@ -122,6 +135,13 @@ func (r *WorldRenderer) Init(w *world.World) (err error) { r.shader.SetUniformTextureHandle("gNorm", r.gbuffer.norm) r.shader.SetUniformTextureHandle("gColor", r.gbuffer.color) + // generate FBO for water rendering + gl.GenFramebuffers(1, &r.water.fbo) + gl.BindFramebuffer(gl.FRAMEBUFFER, r.water.fbo) + gl.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, r.gbuffer.depth) + gl.DrawBuffer(gl.BACK) + gl.ReadBuffer(gl.BACK) + gl.BindFramebuffer(gl.FRAMEBUFFER, 0) r.lastDisplaySize = io.DisplaySize @@ -136,6 +156,7 @@ func (r *WorldRenderer) ResizeDisplay(newSize itype.Vec2i) { } var sun = [3]float32{0.2, 0.4, 0.3} +var alpha float32 = 0.55 func (r *WorldRenderer) Render(world *world.World, view *View) { io.RenderPos = io.ViewPos @@ -149,13 +170,14 @@ func (r *WorldRenderer) Render(world *world.World, view *View) { gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA16F, int32(io.DisplaySize[0]), int32(io.DisplaySize[1]), 0, gl.RGBA, gl.FLOAT, nil) gl.BindTexture(gl.TEXTURE_2D, r.gbuffer.color) gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(io.DisplaySize[0]), int32(io.DisplaySize[1]), 0, gl.RGBA, gl.UNSIGNED_BYTE, nil) - gl.BindRenderbuffer(gl.RENDERBUFFER, r.gbuffer.norm) + gl.BindRenderbuffer(gl.RENDERBUFFER, r.gbuffer.depth) gl.RenderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, int32(io.DisplaySize[0]), int32(io.DisplaySize[1])) r.lastDisplaySize = io.DisplaySize } imgui.SliderFloat3("Sun", &sun, -1, 1) normalSun := itype.Vec3f(sun).Normalize() + imgui.SliderFloat("Water Alpha", &alpha, 0, 1) gl.Enable(gl.CULL_FACE) gl.Enable(gl.DEPTH_TEST) @@ -178,6 +200,7 @@ func (r *WorldRenderer) Render(world *world.World, view *View) { r.depthmap.shader.SetUniformMat4("lightspace", lightspace) world.Render() + world.RenderWater() // 2. Geometry pass, render to G-buffer io.RenderPos = io.ViewPos @@ -201,10 +224,9 @@ func (r *WorldRenderer) Render(world *world.World, view *View) { gl.BindFramebuffer(gl.FRAMEBUFFER, 0) // 3. Render the actual output with deferred lighting - gl.Clear(gl.DEPTH_BUFFER_BIT) + gl.Disable(gl.DEPTH_TEST) r.shader.UseProgram() r.shader.BindTextures() - r.shader.SetUniformMat4("lightspace", lightspace) r.shader.SetUniformVec3f("viewPos", view.EyePos) r.shader.SetUniformVec4f("fogColor", itype.Vec4f{0.6, 0.8, 1.0, 1.0}) @@ -212,6 +234,26 @@ func (r *WorldRenderer) Render(world *world.World, view *View) { DrawScreenQuad() + // 4. Render water + gl.Enable(gl.DEPTH_TEST) + gl.DepthFunc(gl.LESS) + gl.Enable(gl.CULL_FACE) + gl.Enable(gl.BLEND) + gl.BlendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) + gl.BlendEquation(gl.FUNC_ADD) + gl.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, r.gbuffer.depth) + r.water.shader.UseProgram() + r.water.shader.BindTextures() + + r.water.shader.SetUniformMat4("lightspace", lightspace) + r.water.shader.SetUniformMat4("view", view.View()) + r.water.shader.SetUniformMat4("projection", view.Perspective()) + r.water.shader.SetUniformVec3f("viewPos", view.EyePos) + r.water.shader.SetUniformVec3f("sun", normalSun) + r.water.shader.SetUniformFloat("alpha", alpha) + + world.RenderWater() + // Show G-buffers? /*if io.ShowDebugInfo { DrawTexture(r.gbuffer.pos, itype.Rectf{0.5, 0.5, 0.5, 0.5}, DrawTextureChannels_R|DrawTextureChannels_G|DrawTextureChannels_B, 0, 32) diff --git a/internal/world/block.go b/internal/world/block.go index b480bb9..af536e7 100644 --- a/internal/world/block.go +++ b/internal/world/block.go @@ -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. diff --git a/internal/world/blocks/water.go b/internal/world/blocks/water.go index b9871ef..5ff8c67 100644 --- a/internal/world/blocks/water.go +++ b/internal/world/blocks/water.go @@ -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 }, } } diff --git a/internal/world/chunk.go b/internal/world/chunk.go index 4b3acff..553f141 100644 --- a/internal/world/chunk.go +++ b/internal/world/chunk.go @@ -25,7 +25,7 @@ type Chunk struct { vao, vbo uint32 vbolen int } - vertUpdate chan []Vertex + vertUpdate chan [2][]Vertex world *World } diff --git a/internal/world/render.go b/internal/world/render.go index 227beff..ca68a51 100644 --- a/internal/world/render.go +++ b/internal/world/render.go @@ -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 { diff --git a/internal/world/world.go b/internal/world/world.go index ad5fdc5..efb37ca 100644 --- a/internal/world/world.go +++ b/internal/world/world.go @@ -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() + } + +}