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,
|
||||
filter: TextureFilter = Linear,
|
||||
tex_type: TextureType = Tex2D,
|
||||
depth_filter: TextureFilter = Linear,
|
||||
depth_tex_type: TextureType = Tex2D,
|
||||
layer_count = 1,
|
||||
texture: Texture = nil,
|
||||
): Framebuffer
|
||||
proc set_attachments(self: Framebuffer; layer, mipmap_level: int)
|
||||
proc enable*(self: Framebuffer, rect = none((int32,int32,int32,int32)),
|
||||
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 draw*(dest: Framebuffer, shader_mat: Material, inputs: seq[Texture],
|
||||
rect = none((int32,int32,int32,int32)), layer = -1, mipmap_level = 0)
|
||||
|
@ -79,8 +83,17 @@ proc newFramebuffer*(engine: MyouEngine,
|
|||
depth_only = false,
|
||||
filter: TextureFilter = Linear,
|
||||
tex_type: TextureType = Tex2D,
|
||||
depth_filter: TextureFilter = Linear,
|
||||
depth_tex_type: TextureType = Tex2D,
|
||||
layer_count = 1,
|
||||
texture: Texture = nil,
|
||||
): 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
|
||||
# TODO: detect support for float textures and framebuffers in renderer
|
||||
if width == 0 or height == 0:
|
||||
|
@ -97,7 +110,8 @@ proc newFramebuffer*(engine: MyouEngine,
|
|||
if self.texture != nil:
|
||||
# TODO: rely on destructor instead
|
||||
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?
|
||||
self.texture.loaded = true
|
||||
self.texture.setExtrapolation Clamp
|
||||
|
@ -113,24 +127,16 @@ proc newFramebuffer*(engine: MyouEngine,
|
|||
self.depth_texture.destroy()
|
||||
self.depth_texture = nil
|
||||
if depth_type == DepthTexture:
|
||||
# TODO: configure depth tex type?
|
||||
self.depth_texture = engine.newTexture("fb_depth", width, height, 1, depth_format, filter=Linear)
|
||||
self.depth_texture = engine.newTexture("fb_depth", width, height,
|
||||
layer_count, depth_format, tex_type=depth_tex_type,
|
||||
filter=depth_filter)
|
||||
self.depth_texture.loaded = true
|
||||
var fb, rb: GLuint
|
||||
glGenFramebuffers(1, fb.addr)
|
||||
self.framebuffer = fb
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fb)
|
||||
let target = case tex_type:
|
||||
of Tex2D: GL_TEXTURE_2D
|
||||
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:
|
||||
self.set_attachments(0, 0)
|
||||
if depth_type == DepthRenderBuffer:
|
||||
glGenRenderbuffers(1, rb.addr)
|
||||
self.render_buffer = rb
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, rb)
|
||||
|
@ -150,6 +156,23 @@ proc newFramebuffer*(engine: MyouEngine,
|
|||
engine.all_framebuffers.add(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)),
|
||||
layer = -1, mipmap_level = 0, mark_textures = true): Framebuffer {.discardable.} =
|
||||
self.has_mipmap = false
|
||||
|
@ -174,14 +197,7 @@ proc enable*(self: Framebuffer, rect = none((int32,int32,int32,int32)),
|
|||
when not defined(opengl_es):
|
||||
if self.use_sRGB:
|
||||
glEnable(GL_FRAMEBUFFER_SRGB)
|
||||
if self.texture != nil:
|
||||
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.set_attachments(layer, mipmap_level)
|
||||
self.current_mipmap_level = mipmap_level
|
||||
active_layer = layer
|
||||
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
|
||||
return self
|
||||
|
||||
proc clear*(self: Framebuffer, color = vec4(0,0,0,0), clear_color = true, clear_depth = true) {.inline.} =
|
||||
self.enable()
|
||||
proc clear*(self: Framebuffer, color = vec4(0,0,0,0), clear_color = true, clear_depth = true, layer = -1) {.inline.} =
|
||||
self.enable(layer=layer)
|
||||
var bits: uint32
|
||||
if clear_color:
|
||||
glClearColor(color.r, color.g, color.b, color.a)
|
||||
|
|
Loading…
Reference in a new issue