Framebuffer: allow usage of texture arrays and changing type of depth texture.
This commit is contained in:
parent
17d6ccc32d
commit
67f009c157
|
@ -44,11 +44,15 @@ proc newFramebuffer*(engine: MyouEngine,
|
||||||
depth_only = false,
|
depth_only = false,
|
||||||
filter: TextureFilter = Linear,
|
filter: TextureFilter = Linear,
|
||||||
tex_type: TextureType = Tex2D,
|
tex_type: TextureType = Tex2D,
|
||||||
|
depth_filter: TextureFilter = Linear,
|
||||||
|
depth_tex_type: TextureType = Tex2D,
|
||||||
|
layer_count = 1,
|
||||||
texture: Texture = nil,
|
texture: Texture = nil,
|
||||||
): Framebuffer
|
): Framebuffer
|
||||||
|
proc set_attachments(self: Framebuffer; layer, mipmap_level: int)
|
||||||
proc enable*(self: Framebuffer, rect = none((int32,int32,int32,int32)),
|
proc enable*(self: Framebuffer, rect = none((int32,int32,int32,int32)),
|
||||||
layer = -1, mipmap_level = 0, mark_textures = true): Framebuffer {.discardable.}
|
layer = -1, mipmap_level = 0, mark_textures = true): Framebuffer {.discardable.}
|
||||||
proc clear*(self: Framebuffer, color = vec4(0,0,0,0), clear_color = true, clear_depth = true) {.inline.}
|
proc clear*(self: Framebuffer, color = vec4(0,0,0,0), clear_color = true, clear_depth = true, layer = -1) {.inline.}
|
||||||
proc disable*(self: Framebuffer)
|
proc disable*(self: Framebuffer)
|
||||||
proc draw*(dest: Framebuffer, shader_mat: Material, inputs: seq[Texture],
|
proc draw*(dest: Framebuffer, shader_mat: Material, inputs: seq[Texture],
|
||||||
rect = none((int32,int32,int32,int32)), layer = -1, mipmap_level = 0)
|
rect = none((int32,int32,int32,int32)), layer = -1, mipmap_level = 0)
|
||||||
|
@ -79,8 +83,17 @@ proc newFramebuffer*(engine: MyouEngine,
|
||||||
depth_only = false,
|
depth_only = false,
|
||||||
filter: TextureFilter = Linear,
|
filter: TextureFilter = Linear,
|
||||||
tex_type: TextureType = Tex2D,
|
tex_type: TextureType = Tex2D,
|
||||||
|
depth_filter: TextureFilter = Linear,
|
||||||
|
depth_tex_type: TextureType = Tex2D,
|
||||||
|
layer_count = 1,
|
||||||
texture: Texture = nil,
|
texture: Texture = nil,
|
||||||
): Framebuffer =
|
): Framebuffer =
|
||||||
|
|
||||||
|
assert Tex3D notin [tex_type, depth_tex_type],
|
||||||
|
"Tex3D framebuffer not supported"
|
||||||
|
assert TexExternal notin [tex_type, depth_tex_type],
|
||||||
|
"TexExternal framebuffer not supported"
|
||||||
|
|
||||||
let self = new Framebuffer
|
let self = new Framebuffer
|
||||||
# TODO: detect support for float textures and framebuffers in renderer
|
# TODO: detect support for float textures and framebuffers in renderer
|
||||||
if width == 0 or height == 0:
|
if width == 0 or height == 0:
|
||||||
|
@ -97,7 +110,8 @@ proc newFramebuffer*(engine: MyouEngine,
|
||||||
if self.texture != nil:
|
if self.texture != nil:
|
||||||
# TODO: rely on destructor instead
|
# TODO: rely on destructor instead
|
||||||
self.texture.destroy()
|
self.texture.destroy()
|
||||||
self.texture = engine.newTexture("fb_tex", width, height, 1, format, tex_type=tex_type, filter=filter)
|
self.texture = engine.newTexture("fb_tex", width, height,
|
||||||
|
layer_count, format, tex_type=tex_type, filter=filter)
|
||||||
# TODO: set as loaded only after having rendered something?
|
# TODO: set as loaded only after having rendered something?
|
||||||
self.texture.loaded = true
|
self.texture.loaded = true
|
||||||
self.texture.setExtrapolation Clamp
|
self.texture.setExtrapolation Clamp
|
||||||
|
@ -113,24 +127,16 @@ proc newFramebuffer*(engine: MyouEngine,
|
||||||
self.depth_texture.destroy()
|
self.depth_texture.destroy()
|
||||||
self.depth_texture = nil
|
self.depth_texture = nil
|
||||||
if depth_type == DepthTexture:
|
if depth_type == DepthTexture:
|
||||||
# TODO: configure depth tex type?
|
self.depth_texture = engine.newTexture("fb_depth", width, height,
|
||||||
self.depth_texture = engine.newTexture("fb_depth", width, height, 1, depth_format, filter=Linear)
|
layer_count, depth_format, tex_type=depth_tex_type,
|
||||||
|
filter=depth_filter)
|
||||||
self.depth_texture.loaded = true
|
self.depth_texture.loaded = true
|
||||||
var fb, rb: GLuint
|
var fb, rb: GLuint
|
||||||
glGenFramebuffers(1, fb.addr)
|
glGenFramebuffers(1, fb.addr)
|
||||||
self.framebuffer = fb
|
self.framebuffer = fb
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, fb)
|
glBindFramebuffer(GL_FRAMEBUFFER, fb)
|
||||||
let target = case tex_type:
|
self.set_attachments(0, 0)
|
||||||
of Tex2D: GL_TEXTURE_2D
|
if depth_type == DepthRenderBuffer:
|
||||||
of TexCube: GL_TEXTURE_CUBE_MAP_POSITIVE_X
|
|
||||||
of Tex2DArray: GL_TEXTURE_2D_ARRAY
|
|
||||||
of Tex3D: raise ValueError.newException "Tex3D framebuffer not supported"
|
|
||||||
of TexExternal: raise ValueError.newException "TexExternal framebuffer not supported"
|
|
||||||
if self.texture != nil:
|
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, self.texture.storage.tex, 0)
|
|
||||||
if depth_type == DepthTexture:
|
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, self.depth_texture.storage.tex, 0)
|
|
||||||
elif depth_type == DepthRenderBuffer:
|
|
||||||
glGenRenderbuffers(1, rb.addr)
|
glGenRenderbuffers(1, rb.addr)
|
||||||
self.render_buffer = rb
|
self.render_buffer = rb
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, rb)
|
glBindRenderbuffer(GL_RENDERBUFFER, rb)
|
||||||
|
@ -150,6 +156,23 @@ proc newFramebuffer*(engine: MyouEngine,
|
||||||
engine.all_framebuffers.add(self)
|
engine.all_framebuffers.add(self)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
proc set_attachments(self: Framebuffer; layer, mipmap_level: int) =
|
||||||
|
let attachments = [GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT]
|
||||||
|
for i,tex in [self.texture, self.depth_texture]:
|
||||||
|
if tex != nil:
|
||||||
|
if tex.tex_type == Tex2DArray:
|
||||||
|
assert layer >= 0, "Texture array layer must be specified"
|
||||||
|
glFramebufferTextureLayer(GL_FRAMEBUFFER, attachments[i],
|
||||||
|
tex.storage.tex, mipmap_level.GLint, layer.GLint)
|
||||||
|
elif tex.tex_type == TexCube:
|
||||||
|
assert layer >= 0, "Texture cube side must be specified"
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, attachments[i],
|
||||||
|
(GL_TEXTURE_CUBE_MAP_POSITIVE_X.int + layer).GLenum,
|
||||||
|
tex.storage.tex, mipmap_level.GLint)
|
||||||
|
elif self.current_mipmap_level != mipmap_level:
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, attachments[i],
|
||||||
|
tex.storage.target, tex.storage.tex, mipmap_level.GLint)
|
||||||
|
|
||||||
proc enable*(self: Framebuffer, rect = none((int32,int32,int32,int32)),
|
proc enable*(self: Framebuffer, rect = none((int32,int32,int32,int32)),
|
||||||
layer = -1, mipmap_level = 0, mark_textures = true): Framebuffer {.discardable.} =
|
layer = -1, mipmap_level = 0, mark_textures = true): Framebuffer {.discardable.} =
|
||||||
self.has_mipmap = false
|
self.has_mipmap = false
|
||||||
|
@ -174,14 +197,7 @@ proc enable*(self: Framebuffer, rect = none((int32,int32,int32,int32)),
|
||||||
when not defined(opengl_es):
|
when not defined(opengl_es):
|
||||||
if self.use_sRGB:
|
if self.use_sRGB:
|
||||||
glEnable(GL_FRAMEBUFFER_SRGB)
|
glEnable(GL_FRAMEBUFFER_SRGB)
|
||||||
if self.texture != nil:
|
self.set_attachments(layer, mipmap_level)
|
||||||
if layer != -1:
|
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
|
||||||
(GL_TEXTURE_CUBE_MAP_POSITIVE_X.int + layer).GLenum,
|
|
||||||
self.texture.storage.tex, mipmap_level.GLint)
|
|
||||||
elif self.current_mipmap_level != mipmap_level:
|
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
|
||||||
self.texture.storage.target, self.texture.storage.tex, mipmap_level.GLint)
|
|
||||||
self.current_mipmap_level = mipmap_level
|
self.current_mipmap_level = mipmap_level
|
||||||
active_layer = layer
|
active_layer = layer
|
||||||
glViewport(left, bottom, width, height)
|
glViewport(left, bottom, width, height)
|
||||||
|
@ -199,8 +215,8 @@ proc enable*(self: Framebuffer, rect = none((int32,int32,int32,int32)),
|
||||||
# filters_should_blend = self.filters_should_blend
|
# filters_should_blend = self.filters_should_blend
|
||||||
return self
|
return self
|
||||||
|
|
||||||
proc clear*(self: Framebuffer, color = vec4(0,0,0,0), clear_color = true, clear_depth = true) {.inline.} =
|
proc clear*(self: Framebuffer, color = vec4(0,0,0,0), clear_color = true, clear_depth = true, layer = -1) {.inline.} =
|
||||||
self.enable()
|
self.enable(layer=layer)
|
||||||
var bits: uint32
|
var bits: uint32
|
||||||
if clear_color:
|
if clear_color:
|
||||||
glClearColor(color.r, color.g, color.b, color.a)
|
glClearColor(color.r, color.g, color.b, color.a)
|
||||||
|
|
Loading…
Reference in a new issue