-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
Release Type: Official Release
Version: 4.2.0.2381
Platform(s): Windows and Linux with OpenGL set as the renderer
Describe the bug
When using Myra, the screen becomes black if there is any ui being rendered. I am still not sure if it's an issue with Myra, but from what I've seen it's calling the same methods when rendering no matter what graphics api is being used. The critical part is in here where the scissor is being set again. The setter for that property calls a method in Stride Game.GraphicsContext.CommandList.SetScissorRectangle
which makes the screen completely black. If we remove that single part, the renderer works just fine.
I am not too acquainted with this part of Stride, so I'm not sure what that method does in the first place. If anyone has any idea, I would appreciate if you chimed in.
To Reproduce
Steps to reproduce the behavior:
- Follow this guide to create a new project with Myra UI.
- Open
MyGame.Windows.csproj
file and add<StrideGraphicsApi>OpenGL</StrideGraphicsApi>
in the same group as<TargetFramework>
. - Build the game and see a black screen
If you want to test out rendering without calling the faulty method, you can use this extension script and in MyraRenderer
call desktop.RenderLinux
instead of desktop.Render
. You don't have to use Linux for this to work obviously.
using Myra.Graphics2D.UI;
using Myra.Graphics2D;
using Myra;
using System.Reflection;
namespace LD57.UiSystem
{
public static partial class MyraExtensions
{
static MyraExtensions()
{
t_myraContext = typeof(Desktop).GetField("_renderContext", FIND_ANY_FLAGS);
t_inputContext = typeof(Desktop).GetField("_inputContext", FIND_ANY_FLAGS);
t_deviceScissor = typeof(RenderContext).GetProperty("DeviceScissor", FIND_ANY_FLAGS);
t_childrenCopy = typeof(Desktop).GetProperty("ChildrenCopy", FIND_ANY_FLAGS);
t_widgetProcessInput = typeof(Widget).GetMethod("ProcessInput", FIND_ANY_FLAGS);
t_iem = typeof(Widget).Assembly.GetTypes().Where(x => x.FullName.Contains("InputEventsManager")).FirstOrDefault();
t_processEvents = t_iem.GetMethod("ProcessEvents", FIND_ANY_FLAGS);
t_queue = t_iem.GetMethod("Queue", FIND_ANY_FLAGS);
t_layoutBounds = typeof(Desktop).GetProperty("LayoutBounds", FIND_ANY_FLAGS);
t_transform = typeof(Desktop).GetProperty("Transform", FIND_ANY_FLAGS);
}
const BindingFlags FIND_ANY_FLAGS = BindingFlags.Instance |
BindingFlags.Static |
BindingFlags.NonPublic |
BindingFlags.Public;
private static FieldInfo t_myraContext;
private static FieldInfo t_inputContext;
private static PropertyInfo t_deviceScissor;
private static PropertyInfo t_childrenCopy;
private static MethodInfo t_widgetProcessInput;
private static Type t_iem;
private static MethodInfo t_processEvents;
private static MethodInfo t_queue;
private static PropertyInfo t_layoutBounds;
private static PropertyInfo t_transform;
public static void RenderLinux(this Desktop desktop)
{
var inputContext = (InputContext)t_inputContext.GetValue(desktop);
desktop.UpdateLayout();
desktop.UpdateInput();
inputContext.Reset();
foreach (var item in ((List<Widget>)t_childrenCopy.GetValue(desktop))
.Reverse<Widget>())
{
t_widgetProcessInput.Invoke(item, [inputContext]);
}
if (inputContext.MouseWheelWidget != null)
{
t_queue.Invoke(null, [inputContext.MouseWheelWidget, 3]);
}
t_processEvents.Invoke(null, []);
desktop.UpdateLayout();
desktop.RenderVisualLinux();
}
public static void RenderVisualLinux(this Desktop desktop)
{
var layoutBounds = (Rectangle)t_layoutBounds.GetValue(desktop);
var myraContext = (RenderContext)t_myraContext.GetValue(desktop);
var scissors = (Rectangle)t_deviceScissor.GetValue(myraContext);
myraContext.Begin();
myraContext.Transform = (Transform)t_transform.GetValue(desktop);
Rectangle rectangle = myraContext.Transform.Apply(layoutBounds);
myraContext.Scissor = rectangle;
myraContext.Opacity = desktop.Opacity;
if (desktop.Background != null)
{
desktop.Background.Draw(myraContext, layoutBounds);
}
var widgetsCopy = (List<Widget>)t_childrenCopy.GetValue(desktop);
foreach (var child in widgetsCopy)
{
if (child.Visible)
{
child.InvalidateArrange();
child.InvalidateMeasure();
child.Arrange(layoutBounds);
}
}
foreach (Widget item in widgetsCopy)
{
if (item.Visible)
{
if (MyraEnvironment.EnableModalDarkening && item.IsModal)
{
myraContext.FillRectangle(rectangle, MyraEnvironment.DarkeningColor);
}
item.Render(myraContext);
}
}
myraContext.End();
myraContext.Flush();
// This breaks on linux / OpenGL
// t_deviceScissor.SetValue(myraContext, scissors);
}
}
}
Expected behavior
The ui and the rest of the game rendering the same as on the default Graphics API for Windows.