godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
90.1k stars 21.16k forks source link

C# VisualServer can't get the correct Texture RID #35828

Open 4d49 opened 4 years ago

4d49 commented 4 years ago

Godot version: 3.2 stable

OS/device including version: Windows 10

Issue description: If you try to use VisualServer and the Texture RID then you will get an error. I wanted to draw a texture using VisualServer.

E 0:00:01.026 IntPtr Godot.RID.GetPtr(Godot.RID ): System.NullReferenceException: The instance of type RID is null. <C++ Error> Unhandled exception <C++ Source> /root/godot/modules/mono/glue/GodotSharp/GodotSharp/Core/RID.cs:15 @ IntPtr Godot.RID.GetPtr(Godot.RID )()

RID.cs:15 @ IntPtr Godot.RID.GetPtr(Godot.RID )() VisualServer.cs:4683 @ void Godot.VisualServer.CanvasItemAddTextureRect(Godot.RID , Godot.Rect2 , Godot.RID , Boolean , System.Nullable`1[Godot.Color] , Boolean , Godot.RID )() test.cs:15 @ void test._Ready()()

Steps to reproduce: Just create a new Node2D and assign the script.

Minimal reproduction project:

using Godot;
using System;

public class test : Node2D {
    [Export]
    public Texture texture;

    [Export]
    public Rect2 rect2;

    public override void _Ready() {
        GD.Print(texture.GetRid());
        RID item = VisualServer.CanvasItemCreate();
        VisualServer.CanvasItemSetParent(item, GetCanvasItem());
        VisualServer.CanvasItemAddTextureRect(item, rect2, texture.GetRid());
    }
}
jasonswearingen commented 4 years ago

@TvoyBatek umm... it looks like you never assign an object to texture ??? at least in code you pasted. does it gets assigned via the editor?

4d49 commented 4 years ago

@TvoyBatek umm... it looks like you never assign an object to texture ??? at least in code you pasted. does it gets assigned via the editor?

I assign a texture from Inspector. GP.Print prints the RID, but VisualServer gets an error.

4d49 commented 4 years ago

In any case, I tried getting the texture through the ResourceLoader.load().

4d49 commented 4 years ago

If the code looks like this then everything works.

    public override void _Ready() {
        RID item = VisualServer.CanvasItemCreate();
        VisualServer.CanvasItemSetParent(item, GetCanvasItem());
        VisualServer.CanvasItemAddTextureRect(item, rect2, texture.GetRid(), false, new Color(1, 1, 1, 1), false, texture.GetRid());
    }
GeorgeS2019 commented 4 years ago

@TvoyBatek have a look at this VisualServer discussion.

KoBeWi commented 3 years ago

Can anyone still reproduce this bug in Godot 3.2.3 or any later release?

opl- commented 3 years ago

I can reproduce this on 3.2.3. The issue is with the normalMap argument:

[GodotMethod("canvas_item_add_texture_rect")]
public static void CanvasItemAddTextureRect(RID item, Rect2 rect, RID texture, bool tile = false, Color? modulate = null, bool transpose = false, RID normalMap = null)
{
    Color arg = modulate.HasValue ? modulate.Value : new Color(1f, 1f, 1f);
    NativeCalls.godot_icall_7_992(method_bind_296, ptr, RID.GetPtr(item), ref rect, RID.GetPtr(texture), tile, ref arg, transpose, RID.GetPtr(normalMap));
}
}

RID.GetPtr(normalMap) throws if the passed in value is null, which is what the argument defaults to. Problem is, passing null to the normalMap should of course be permitted.

Using VisualServer.CanvasItemAddTextureRect(rid, new Rect2(0f, 0f, 1f, 1f), texture.GetRid(), normalMap: new RID(null)); seems to correctly result in a null pointer getting passed to the server.

This seems to have been changed in 008769aee9ccacdf5098a1088fcd6cfd52c0644d (#33703) by @neikeq.

SlawekNowy commented 1 year ago

Not applicable in Godot 4.0, as the offending method no longer accepts normalMap.

SlawekNowy commented 1 year ago

However it is confirmed on Godot 3.5.2