Optimizing Dialog and Tooltip Rendering in GameMaker
Surface based GUI Rendering Technique
This document outlines an optimization technique for rendering dialogs and tooltips in GameMaker games, especially useful for games with varying display resolutions. Example in my game my Camera width and height are 420x236 while the viewport width and height is 1920x1080px.
DEMO:
https://youtu.be/5Xhd9O3Wevo
Key Concepts
- Surface Creation: We create a surface matching the viewport dimensions (e.g., 1920x1080).
- Render-to-Texture: Dialog/tooltip content is drawn onto this surface.
- Scaling: The surface is then stretched to fit the current GUI dimensions.
Benefits
- Consistent appearance across different screen sizes
- Improved performance through selective redrawing
- Better scaling quality
Following are just brief sections related to surface rendering not the entire code on how to create a Dialog with options. Link to itch has al code you need.
Implementation for Dialogs
Object Creation
dialog_surface = -1;
surface_width = 1920; // Match viewport width
surface_height = 1080; // Match viewport height
_needs_redraw = true;
Drawing Logic (Draw GUI event)
if (dialog_active && current_dialog != noone) {
if (!surface_exists(dialog_surface)) {
dialog_surface = surface_create(surface_width, surface_height);
_needs_redraw = true;
}
if (_needs_redraw) {
surface_set_target(dialog_surface);
draw_clear_alpha(c_black, 0);
// Draw dialog content here
surface_reset_target();
_needs_redraw = true;
}
// Draw stretched surface
draw_surface_stretched(dialog_surface, 0, 0,
display_get_gui_width(),
display_get_gui_height());
}
Implementation for Tooltips
Similar to dialogs, but typically with different positioning logic.
Key Differences for Tooltips
- Often need to follow game objects
- May require camera-relative positioning
Step event would
// In Step Event
var _cam_x = camera_get_view_x(view_camera[0]);
var _cam_y = camera_get_view_y(view_camera[0]);
x = (_init_x - _cam_x) * (surface_width / camera_get_view_width(view_camera[0]));
y = (_init_y - _cam_y) * (surface_height / camera_get_view_height(view_camera[0]));
Best Practices
Redraw Flags: Use _needs_redraw to avoid unnecessary rendering.
Scale Calculations: Pre-calculate scaling factors when possible.
Surface Management: Always check if the surface exists before using it.
Clean Up: Free surfaces when objects are destroyed or rooms end.
Conclusion
This technique significantly improves rendering quality and performance for UI elements like dialogs and tooltips. It ensures consistent appearance across different display sizes while optimizing draw calls.
Top comments (1)
The screenshots look good!