import "luxe: render" for Render, RenderLayerDesc, PassLayerDesc, LoadAction import "luxe: render" for SortType, ImageDesc, ImageType, PixelFormat, Image import "luxe: math" for Math import "luxe: io" for IO import "luxe: events" for Events import "math/math" for M import "math/util" for Util import "math/vector" for Vector import "math/rect" for AABB import "globals" for Globals import "blocks/debug" for Holder class Renderer { target{ "scene" } static on_change{ "change" } static pixel_width{128} pixel_width{Renderer.pixel_width} res{_gameRes} width{_gameRes.x} height{_gameRes.y} pixel_size{_pixel_size} events{_events} construct new() { Globals["Renderer"] = this _events = Events.new() _desc = ImageDesc.new() _desc.type = ImageType.image2D _desc.pixel_format = PixelFormat.rgba8Unorm _desc.width = pixel_width _desc.height = pixel_width _rt = Image.create(_desc) Render.define_resource(target, _rt) Log.print("game / render / init / ok") } //new update_targets(){ var window = Vector.new(Render.window_w(), Render.window_h()) _pixel_size = (window.x / pixel_width).floor _gameRes = window / _pixel_size _gameRes = _gameRes - _gameRes % 2 Log.print("game is now %(res.x) x %(res.y)") Globals["GameRect"] = AABB.new((_gameRes.x - pixel_width) / 2, _gameRes.y - pixel_width, pixel_width, pixel_width) Globals["UiRect"] = AABB.new(0, 0, _gameRes.x, _gameRes.y - pixel_width) var relGameRect = AABB.new(Globals["GameRect"].pos.y0() / _gameRes, Vector.new(pixel_width) / _gameRes) Globals["RelativeGameRect"] = relGameRect _desc.width = res.x _desc.height = res.y Image.redefine(_rt, _desc) _texRect = AABB.new((window - _gameRes*_pixel_size)/2, _gameRes * _pixel_size) events.emit(Renderer.on_change) } game_mouse(mouse_pos){ var pixel_game_rect = Globals["GameRect"] var window = AABB.new(0, 0, Render.window_w(), Render.window_h()) //what a mess :/ var screen = AABB.new(_texRect.min_x + pixel_game_rect.min_x * _pixel_size, Render.window_h() - (_texRect.min_y + pixel_game_rect.max_y * _pixel_size), pixel_game_rect.width * _pixel_size, pixel_game_rect.height * _pixel_size) return M.remap(screen.min, screen.max, window.min, window.max, mouse_pos) } ui_mouse(mouse_pos){ //good chance this works by luck and is not exact var window = AABB.new(0, 0, Render.window_w(), Render.window_h()) var screen = AABB.new(_texRect.min_x, Render.window_h() - _texRect.max_y, _texRect.width, _texRect.height) //Y- mouse positions are the bane of my existance return M.remap(screen.min, screen.max, window.min, window.max, mouse_pos) } ready() { update_targets() IO.on("engine.runtime.window.size_changed") {|type, data| update_targets() } } tick(delta) { } render_path(ctx) { if(ctx.path == "game") { game_render_path(ctx) } else if(ctx.path == "ui") { ui_render_path(ctx) } else if(ctx.path == "copy_to_screen") { target_to_screen(ctx) } else if(ctx.path == "clear"){ clear(ctx) } } //render_path game_render_path(ctx) { var layer = RenderLayerDesc.new() layer.sort = SortType.front_to_back layer.dest.color[0].render_target = target layer.dest.color[0].clear_color = ctx.get("clear_color", [1,1,1,1]) layer.dest.color[0].load_action = LoadAction.clear layer.dest.depth.load_action = LoadAction.clear ctx.layer_render("default", layer) } //game_render_path ui_render_path(ctx) { var layer = RenderLayerDesc.new() layer.sort = SortType.sort_by_z_reverse layer.dest.color[0].render_target = target layer.dest.color[0].load_action = LoadAction.dont_care layer.dest.depth.load_action = LoadAction.clear ctx.layer_render("default", layer) } //ui_render_path target_to_screen(ctx){ //{ library="luxe: shaders" function="vert_color_uv" } var out_pass = PassLayerDesc.new() out_pass.fragment.library = "shaders/upscale" out_pass.fragment.function = "upscale_top_center" out_pass.targets = ["screen"] out_pass.inputs = { "pass.flipy" : true, "pass.rect" : _texRect.pos_size_list, "pass.image" : { "image": target, //image resource name "sampler": "nearest_clamp" //sampler state }, } ctx.layer_pass(out_pass) } clear(ctx){ var layer = RenderLayerDesc.new() layer.dest.color[0].render_target = target layer.dest.color[0].clear_color = [0,0,0,1] layer.dest.color[0].load_action = LoadAction.clear layer.dest.depth.load_action = LoadAction.clear ctx.layer_render("default", layer) } } //Renderer