gpu: add depthBits parameter to NewFramebuffer

Along with ReadPixels in the next change, a Framebuffer with depth is enough to
implement screenshot functionality on top of any Backend.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2020-02-22 07:53:49 +01:00
parent 10484d26f3
commit 6fd545a4d8
4 changed files with 37 additions and 6 deletions
+1 -1
View File
@@ -20,7 +20,7 @@ type Backend interface {
IsTimeContinuous() bool IsTimeContinuous() bool
NewTexture(format TextureFormat, width, height int, minFilter, magFilter TextureFilter, bindings BufferBinding) (Texture, error) NewTexture(format TextureFormat, width, height int, minFilter, magFilter TextureFilter, bindings BufferBinding) (Texture, error)
DefaultFramebuffer() Framebuffer DefaultFramebuffer() Framebuffer
NewFramebuffer(tex Texture) (Framebuffer, error) NewFramebuffer(tex Texture, depthBits int) (Framebuffer, error)
NewImmutableBuffer(typ BufferBinding, data []byte) (Buffer, error) NewImmutableBuffer(typ BufferBinding, data []byte) (Buffer, error)
NewBuffer(typ BufferBinding, size int) (Buffer, error) NewBuffer(typ BufferBinding, size int) (Buffer, error)
NewProgram(vertexShader, fragmentShader ShaderSources) (Program, error) NewProgram(vertexShader, fragmentShader ShaderSources) (Program, error)
+29 -4
View File
@@ -54,11 +54,15 @@ type gpuTexture struct {
backend *Backend backend *Backend
obj Texture obj Texture
triple textureTriple triple textureTriple
width int
height int
} }
type gpuFramebuffer struct { type gpuFramebuffer struct {
funcs Functions funcs Functions
obj Framebuffer obj Framebuffer
hasDepth bool
depthBuf Renderbuffer
} }
type gpuBuffer struct { type gpuBuffer struct {
@@ -162,7 +166,7 @@ func (b *Backend) IsTimeContinuous() bool {
return b.funcs.GetInteger(GPU_DISJOINT_EXT) == FALSE return b.funcs.GetInteger(GPU_DISJOINT_EXT) == FALSE
} }
func (b *Backend) NewFramebuffer(tex gpu.Texture) (gpu.Framebuffer, error) { func (b *Backend) NewFramebuffer(tex gpu.Texture, depthBits int) (gpu.Framebuffer, error) {
glErr(b.funcs) glErr(b.funcs)
gltex := tex.(*gpuTexture) gltex := tex.(*gpuTexture)
fb := b.funcs.CreateFramebuffer() fb := b.funcs.CreateFramebuffer()
@@ -173,6 +177,24 @@ func (b *Backend) NewFramebuffer(tex gpu.Texture) (gpu.Framebuffer, error) {
return nil, err return nil, err
} }
b.funcs.FramebufferTexture2D(FRAMEBUFFER, COLOR_ATTACHMENT0, TEXTURE_2D, gltex.obj, 0) b.funcs.FramebufferTexture2D(FRAMEBUFFER, COLOR_ATTACHMENT0, TEXTURE_2D, gltex.obj, 0)
if depthBits > 0 {
size := Enum(DEPTH_COMPONENT16)
switch {
case depthBits > 24:
size = DEPTH_COMPONENT32F
case depthBits > 16:
size = DEPTH_COMPONENT24
}
depthBuf := b.funcs.CreateRenderbuffer()
b.funcs.BindRenderbuffer(RENDERBUFFER, depthBuf)
b.funcs.RenderbufferStorage(RENDERBUFFER, size, gltex.width, gltex.height)
fbo.depthBuf = depthBuf
fbo.hasDepth = true
if err := glErr(b.funcs); err != nil {
fbo.Release()
return nil, err
}
}
if st := b.funcs.CheckFramebufferStatus(FRAMEBUFFER); st != FRAMEBUFFER_COMPLETE { if st := b.funcs.CheckFramebufferStatus(FRAMEBUFFER); st != FRAMEBUFFER_COMPLETE {
fbo.Release() fbo.Release()
return nil, fmt.Errorf("incomplete framebuffer, status = 0x%x, err = %d", st, b.funcs.GetError()) return nil, fmt.Errorf("incomplete framebuffer, status = 0x%x, err = %d", st, b.funcs.GetError())
@@ -186,7 +208,7 @@ func (b *Backend) DefaultFramebuffer() gpu.Framebuffer {
func (b *Backend) NewTexture(format gpu.TextureFormat, width, height int, minFilter, magFilter gpu.TextureFilter, binding gpu.BufferBinding) (gpu.Texture, error) { func (b *Backend) NewTexture(format gpu.TextureFormat, width, height int, minFilter, magFilter gpu.TextureFilter, binding gpu.BufferBinding) (gpu.Texture, error) {
glErr(b.funcs) glErr(b.funcs)
tex := &gpuTexture{backend: b, obj: b.funcs.CreateTexture()} tex := &gpuTexture{backend: b, obj: b.funcs.CreateTexture(), width: width, height: height}
switch format { switch format {
case gpu.TextureFormatFloat: case gpu.TextureFormatFloat:
tex.triple = b.floatTriple tex.triple = b.floatTriple
@@ -578,6 +600,9 @@ func (f *gpuFramebuffer) Invalidate() {
func (f *gpuFramebuffer) Release() { func (f *gpuFramebuffer) Release() {
f.funcs.DeleteFramebuffer(f.obj) f.funcs.DeleteFramebuffer(f.obj)
if f.hasDepth {
f.funcs.DeleteRenderbuffer(f.depthBuf)
}
} }
func toTexFilter(f gpu.TextureFilter) int { func toTexFilter(f gpu.TextureFilter) int {
+6
View File
@@ -17,6 +17,8 @@ const (
DEPTH_BUFFER_BIT = 0x100 DEPTH_BUFFER_BIT = 0x100
DEPTH_ATTACHMENT = 0x8d00 DEPTH_ATTACHMENT = 0x8d00
DEPTH_COMPONENT16 = 0x81a5 DEPTH_COMPONENT16 = 0x81a5
DEPTH_COMPONENT24 = 0x81A6
DEPTH_COMPONENT32F = 0x8CAC
DEPTH_TEST = 0xb71 DEPTH_TEST = 0xb71
DST_COLOR = 0x306 DST_COLOR = 0x306
ELEMENT_ARRAY_BUFFER = 0x8893 ELEMENT_ARRAY_BUFFER = 0x8893
@@ -91,6 +93,7 @@ type Functions interface {
BindAttribLocation(p Program, a Attrib, name string) BindAttribLocation(p Program, a Attrib, name string)
BindBuffer(target Enum, b Buffer) BindBuffer(target Enum, b Buffer)
BindFramebuffer(target Enum, fb Framebuffer) BindFramebuffer(target Enum, fb Framebuffer)
BindRenderbuffer(target Enum, fb Renderbuffer)
BindTexture(target Enum, t Texture) BindTexture(target Enum, t Texture)
BlendEquation(mode Enum) BlendEquation(mode Enum)
BlendFunc(sfactor, dfactor Enum) BlendFunc(sfactor, dfactor Enum)
@@ -104,12 +107,14 @@ type Functions interface {
CreateFramebuffer() Framebuffer CreateFramebuffer() Framebuffer
CreateProgram() Program CreateProgram() Program
CreateQuery() Query CreateQuery() Query
CreateRenderbuffer() Renderbuffer
CreateShader(ty Enum) Shader CreateShader(ty Enum) Shader
CreateTexture() Texture CreateTexture() Texture
DeleteBuffer(v Buffer) DeleteBuffer(v Buffer)
DeleteFramebuffer(v Framebuffer) DeleteFramebuffer(v Framebuffer)
DeleteProgram(p Program) DeleteProgram(p Program)
DeleteQuery(query Query) DeleteQuery(query Query)
DeleteRenderbuffer(r Renderbuffer)
DeleteShader(s Shader) DeleteShader(s Shader)
DeleteTexture(v Texture) DeleteTexture(v Texture)
DepthFunc(f Enum) DepthFunc(f Enum)
@@ -134,6 +139,7 @@ type Functions interface {
GetUniformLocation(p Program, name string) Uniform GetUniformLocation(p Program, name string) Uniform
InvalidateFramebuffer(target, attachment Enum) InvalidateFramebuffer(target, attachment Enum)
LinkProgram(p Program) LinkProgram(p Program)
RenderbufferStorage(target, internalformat Enum, width, height int)
ShaderSource(s Shader, src string) ShaderSource(s Shader, src string)
TexImage2D(target Enum, level int, internalFormat int, width, height int, format, ty Enum, data []byte) TexImage2D(target Enum, level int, internalFormat int, width, height int, format, ty Enum, data []byte)
TexParameteri(target, pname Enum, param int) TexParameteri(target, pname Enum, param int)
+1 -1
View File
@@ -213,7 +213,7 @@ func (s *fboSet) resize(ctx Backend, sizes []image.Point) {
} }
tex, err := ctx.NewTexture(TextureFormatFloat, sz.X, sz.Y, FilterNearest, FilterNearest, tex, err := ctx.NewTexture(TextureFormatFloat, sz.X, sz.Y, FilterNearest, FilterNearest,
BufferBindingTexture|BufferBindingFramebuffer) BufferBindingTexture|BufferBindingFramebuffer)
fbo, err := ctx.NewFramebuffer(tex) fbo, err := ctx.NewFramebuffer(tex, 0)
if err != nil { if err != nil {
panic(err) panic(err)
} }