Property definitions

gamnit $ DynamicContext :: defaultinit
# Handles to reused GL buffers and texture
private class DynamicContext

	# Dynamic screen framebuffer
	var dynamic_framebuffer: Int = -1

	# Depth renderbuffer attached to `dynamic_framebuffer`
	var depth_renderbuffer: Int = -1

	# Texture attached to `dynamic_framebuffer` as color attachment
	var 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, max_dynamic_resolution_ratio: Float)
	do
		# TODO enable antialiasing.

		# Framebuffer
		var framebuffer = glGenFramebuffers(1).first
		glBindFramebuffer(gl_FRAMEBUFFER, framebuffer)
		assert glIsFramebuffer(framebuffer)
		self.dynamic_framebuffer = framebuffer
		assert glGetError == gl_NO_ERROR

		# Depth & texture/color
		var depthbuffer = glGenRenderbuffers(1).first
		self.depth_renderbuffer = depthbuffer
		var texture = glGenTextures(1).first
		self.texture = texture
		assert glGetError == gl_NO_ERROR

		resize(display, max_dynamic_resolution_ratio)
		assert glCheckFramebufferStatus(gl_FRAMEBUFFER) == gl_FRAMEBUFFER_COMPLETE

		# Array buffer
		buffer_array = glGenBuffers(1).first
		glBindBuffer(gl_ARRAY_BUFFER, buffer_array)
		assert glIsBuffer(buffer_array)
		assert glGetError == gl_NO_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)

		assert glGetError == gl_NO_ERROR
	end

	# Init size or resize `depth_renderbuffer` and `texture`
	fun resize(display: GamnitDisplay, max_dynamic_resolution_ratio: Float)
	do
		var width = (display.width.to_f * max_dynamic_resolution_ratio).to_i
		var height = (display.height.to_f * max_dynamic_resolution_ratio).to_i

		glBindFramebuffer(gl_FRAMEBUFFER, dynamic_framebuffer)

		var depthbuffer = self.depth_renderbuffer
		var texture = self.texture

		# Depth
		glBindRenderbuffer(gl_RENDERBUFFER, depthbuffer)
		assert glIsRenderbuffer(depthbuffer)
		glRenderbufferStorage(gl_RENDERBUFFER, gl_DEPTH_COMPONENT16, width, height)
		glFramebufferRenderbuffer(gl_FRAMEBUFFER, gl_DEPTH_ATTACHMENT, gl_RENDERBUFFER, depthbuffer)
		assert glGetError == gl_NO_ERROR

		# Texture
		glBindTexture(gl_TEXTURE_2D, texture)
		glTexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MIN_FILTER, gl_LINEAR)
		glTexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, gl_LINEAR)
		glTexParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_S, gl_CLAMP_TO_EDGE)
		glTexParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_T, gl_CLAMP_TO_EDGE)
		glTexImage2D(gl_TEXTURE_2D, 0, gl_RGB, width, height,
		             0, gl_RGB, gl_UNSIGNED_BYTE, new Pointer.nul)
		glFramebufferTexture2D(gl_FRAMEBUFFER, gl_COLOR_ATTACHMENT0, gl_TEXTURE_2D, texture, 0)

		assert glGetError == gl_NO_ERROR

		# Take down
		glBindRenderbuffer(gl_RENDERBUFFER, 0)
		glBindFramebuffer(gl_FRAMEBUFFER, 0)

		assert glGetError == gl_NO_ERROR
	end

	var destroyed = false
	fun destroy
	do
		if destroyed then return
		destroyed = true

		# Free the buffer
		glDeleteBuffers([buffer_array])
		assert glGetError == gl_NO_ERROR
		buffer_array = -1

		# Free the dynamic framebuffer and its attachments
		glDeleteBuffers([buffer_array])
		glDeleteFramebuffers([dynamic_framebuffer])
		glDeleteRenderbuffers([depth_renderbuffer])
		glDeleteTextures([texture])
	end
end
lib/gamnit/dynamic_resolution.nit:187,1--303,3