Screen: Add newFramebufferScreen, newTextureScreen, setTexture.

This commit is contained in:
Alberto Torres 2025-01-21 18:46:17 +01:00
parent 2c8c1407ab
commit a56da31656
2 changed files with 54 additions and 1 deletions

View file

@ -50,6 +50,7 @@ proc newFramebuffer*(engine: MyouEngine,
texture: Texture = nil,
): Framebuffer
proc set_attachments(self: Framebuffer; layer, mipmap_level: int)
proc set_texture*(self: Framebuffer, texture: Texture)
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, layer = -1) {.inline.}
@ -174,6 +175,12 @@ proc set_attachments(self: Framebuffer; layer, mipmap_level: int) =
glFramebufferTexture2D(GL_FRAMEBUFFER, attachments[i],
tex.storage.target, tex.storage.tex.GLuint, mipmap_level.GLint)
proc set_texture*(self: Framebuffer, texture: Texture) =
if active_buffer == self:
self.disable()
self.texture = texture
self.current_mipmap_level = -1 # this forces attachment
proc enable*(self: Framebuffer, rect = none((int32,int32,int32,int32)),
layer = -1, mipmap_level = 0, mark_textures = true): Framebuffer {.discardable.} =
self.has_mipmap = false

View file

@ -30,10 +30,19 @@
# License. If you do not delete the provisions above, a recipient may use your
# version of this file under either the CPAL or the [AGPL-3] License.
## In the engine, a screen represents e.g. a screen, a window, a canvas, or a
## render-to-texture framebuffer, with one or more viewports where stuff is drawn
## from the perspective of a camera in a scene.
##
## If it's a screen, window or canvas, it's also the receiver of user events.
import ./types
# Forward declarations
proc newScreen*(engine: MyouEngine, width, height: int32, title: string): Screen
proc newFramebufferScreen*(engine: MyouEngine, fb: Framebuffer): Screen
proc newTextureScreen*(engine: MyouEngine, texture: Texture, depth_type: FramebufferDepthType = DepthRenderBuffer, depth_format = Depth_u24): Screen
proc setTexture*(self: Screen, texture: Texture)
proc destroy*(self: Screen)
proc resize*(self: Screen, width, height: int32, orientation = self.orientation)
proc add_viewport*(self: Screen, camera: Camera)
@ -73,6 +82,42 @@ proc newScreen*(engine: MyouEngine, width, height: int32, title: string): Screen
result.frame_interval = 1
result.display_scale = 1.0
proc newFramebufferScreen*(engine: MyouEngine, fb: Framebuffer): Screen =
## Creates a new virtual screen from a framebuffer to render to it.
result = new Screen
result.engine = engine
result.width = fb.width.int32
result.height = fb.height.int32
result.framebuffer = fb
result.enabled = true
engine.screens.add result
result.resize(result.width, result.height)
result.pre_draw = proc(self: Screen) = discard
result.post_draw = proc(self: Screen) = discard
result.frame_interval = 1
result.display_scale = 1.0
proc newTextureScreen*(engine: MyouEngine, texture: Texture, depth_type: FramebufferDepthType = DepthRenderBuffer, depth_format = Depth_u24): Screen =
## Creates a new virtual screen from a texture to render to it.
# TODO: check that it's not a compressed texture
assert texture.tex_type == Tex2D, "Only 2D textures are supported"
return engine.newFramebufferScreen engine.newFramebuffer(
texture.width, texture.height,
format = texture.format,
texture = texture,
depth_type = depth_type,
depth_format = depth_format,
)
proc setTexture*(self: Screen, texture: Texture) =
## Change the texture of a render-to-texture screen.
assert texture != nil
assert self.framebuffer.texture != nil
self.framebuffer.set_texture texture
proc destroy*(self: Screen) =
## Destroys the screen/window and all its resources. If you destroy the main
## screen, the first screen created after it will become the main screen. If
@ -117,7 +162,8 @@ proc add_viewport*(self: Screen, camera: Camera) =
proc `vsync=`*(self: Screen, vsync: bool) =
## Change the vsync setting of the screen/window.
cast[Window](self.window).set_vsync vsync
if self.window != nil:
cast[Window](self.window).set_vsync vsync
proc get_ray_direction*(viewport: Viewport, position: Vec2): Vec3 =
## Calculates a vector that points from the camera towards the given screen