package render import ( "image/color" "tetris/engine/system" rl "github.com/gen2brain/raylib-go/raylib" ) type Config struct { Title string // Window WindowWidth int32 WindowHeight int32 WindowFlags uint32 // Render target resolution RenderHeight int32 RenderWidth int32 ScaleFlags ScaleFlags } // target is the off-screen render target where all drawing operations are performed. // It has a fixed resolution and is later scaled to the window size. var target rl.RenderTexture2D var scaleFlags ScaleFlags // Init initializes the rendering system. // // It creates an off-screen render texture with the fixed resolution defined by config.RenderWidth/Height. // This texture is where all tiles and game graphics are drawn before being scaled and presented. func Init(config Config) { // hyprland has a bug where the height of the window is 37 pixels taller than requested. // so we just subtract it here. if system.IsHyprland() { config.WindowHeight = config.WindowHeight - 37 } scaleFlags = config.ScaleFlags if config.WindowFlags > 0 { rl.SetConfigFlags(config.WindowFlags) } // Setup window rl.InitWindow(config.WindowWidth, config.WindowHeight, config.Title) // Initialize render texture. target = rl.LoadRenderTexture(config.RenderWidth, config.RenderHeight) rl.SetTextureFilter(target.Texture, rl.TextureFilterNearest) } // Exit shuts down the rendering system. // // It unloads the render texture and frees any associated GPU resources. // This should be called before the application exits. func Exit() { rl.UnloadRenderTexture(target) rl.CloseWindow() } // Begin prepares the rendering system for a new frame. // // It binds the off-screen texture target and clears it to a black background. // All tile drawing operations (e.g., DrawTile) should occur after Begin() and // before End(). func Begin(col color.RGBA) { // Bind texture so that all draw calls after are applied to target texture rl.BeginTextureMode(target) // Clear the texture rl.ClearBackground(col) } // End finalizes the current frame and displays it on the screen. // // It ends the off-screen drawing session and stretches the texture target // to fill the window. This function must be called after all drawing is done. func End() { // End drawing to the texture target. rl.EndTextureMode() // Begin drawing to screen buffer. rl.BeginDrawing() // Define source rectangle (flip vertically to match coordinate systems). src := rl.Rectangle{ X: 0, Y: 0, Width: float32(target.Texture.Width), Height: -float32(target.Texture.Height), } // Calculate the destination rectangle (window). dest := scale(target.Texture.Width, target.Texture.Height, int32(rl.GetRenderWidth()), int32(rl.GetRenderHeight()), scaleFlags) // Blit the off-screen texture to the screen's back buffer. rl.DrawTexturePro(target.Texture, src, dest, rl.Vector2Zero(), 0.0, rl.White) // Swap buffers rl.EndDrawing() }