gamnit :: ShadowContext :: defaultinit
# Handles to reused GL buffers and texture
private class ShadowContext
# Real screen framebuffer
var screen_framebuffer: Int = -1
# Framebuffer for the light point of view
var light_view_framebuffer: Int = -1
# Depth attached to `light_view_framebuffer`
var depth_texture: Int = -1
# Buffer name for vertex data
var buffer_array: Int = -1
# Prepare all attributes once per resolution change
fun prepare_once(display: GamnitDisplay, shadow_resolution: Int)
do
assert display.gl_extensions.has("GL_OES_depth_texture")
# Set aside the real screen framebuffer name
var screen_framebuffer = glGetIntegerv(gl_FRAMEBUFFER_BINDING, 0)
self.screen_framebuffer = screen_framebuffer
# Framebuffer
var framebuffer = glGenFramebuffers(1).first
glBindFramebuffer(gl_FRAMEBUFFER, framebuffer)
assert glIsFramebuffer(framebuffer)
self.light_view_framebuffer = framebuffer
var gl_error = glGetError
assert gl_error == gl_NO_ERROR else print_error gl_error
# Depth & texture/color
var textures = glGenTextures(1)
self.depth_texture = textures[0]
gl_error = glGetError
assert gl_error == gl_NO_ERROR else print_error gl_error
resize(display, shadow_resolution)
# Array buffer
buffer_array = glGenBuffers(1).first
glBindBuffer(gl_ARRAY_BUFFER, buffer_array)
assert glIsBuffer(buffer_array)
gl_error = glGetError
assert gl_error == gl_NO_ERROR else print_error gl_error
## coord
var data = new Array[Float]
data.add_all([-1.0, -1.0, 0.0,
1.0, -1.0, 0.0,
-1.0, 1.0, 0.0,
1.0, 1.0, 0.0])
## tex_coord
data.add_all([0.0, 0.0,
1.0, 0.0,
0.0, 1.0,
1.0, 1.0])
var c_data = new GLfloatArray.from(data)
glBufferData(gl_ARRAY_BUFFER, data.length*4, c_data.native_array, gl_STATIC_DRAW)
glBindBuffer(gl_ARRAY_BUFFER, 0)
gl_error = glGetError
assert gl_error == gl_NO_ERROR else print_error gl_error
end
# Init size or resize `depth_texture`
fun resize(display: GamnitDisplay, shadow_resolution: Int)
do
glBindFramebuffer(gl_FRAMEBUFFER, light_view_framebuffer)
var gl_error = glGetError
assert gl_error == gl_NO_ERROR else print_error gl_error
# Depth texture
var depth_texture = self.depth_texture
glActiveTexture gl_TEXTURE0
glBindTexture(gl_TEXTURE_2D, depth_texture)
glTexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MIN_FILTER, gl_LINEAR)
glTexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, gl_NEAREST)
glTexParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_S, gl_CLAMP_TO_EDGE)
glTexParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_T, gl_CLAMP_TO_EDGE)
gl_error = glGetError
assert gl_error == gl_NO_ERROR else print_error gl_error
# TODO support hardware shadows with GL ES 3.0 or GL_EXT_shadow_samplers
#glTexParameteri(gl_TEXTURE_2D, gl_TEXTURE_COMPARE_MODE, ...)
glTexImage2D(gl_TEXTURE_2D, 0, gl_DEPTH_COMPONENT,
shadow_resolution, shadow_resolution,
0, gl_DEPTH_COMPONENT, gl_UNSIGNED_SHORT, new Pointer.nul)
gl_error = glGetError
assert gl_error == gl_NO_ERROR else print_error gl_error
glFramebufferTexture2D(gl_FRAMEBUFFER, gl_DEPTH_ATTACHMENT, gl_TEXTURE_2D, depth_texture, 0)
gl_error = glGetError
assert gl_error == gl_NO_ERROR else print_error gl_error
# Check if the framebuffer is complete and valid
assert glCheckFramebufferStatus(gl_FRAMEBUFFER) == gl_FRAMEBUFFER_COMPLETE
# Take down
glBindTexture(gl_TEXTURE_2D, 0)
glBindFramebuffer(gl_FRAMEBUFFER, 0)
gl_error = glGetError
assert gl_error == gl_NO_ERROR else print_error gl_error
end
var destroyed = false
fun destroy
do
if destroyed then return
destroyed = true
# Free the buffer
glDeleteBuffers([buffer_array])
var gl_error = glGetError
assert gl_error == gl_NO_ERROR else print_error gl_error
buffer_array = -1
# Free the array and framebuffer plus its attachments
glDeleteBuffers([buffer_array])
glDeleteFramebuffers([light_view_framebuffer])
glDeleteTextures([depth_texture])
end
end
lib/gamnit/depth/shadow.nit:182,1--308,3