made it acutally work in godot, and made it draw a texture
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -53,3 +53,5 @@ CMakeUserPresets.json
|
||||
|
||||
# stupid godot developers using SCons
|
||||
build/
|
||||
|
||||
godot/
|
||||
|
||||
@@ -55,8 +55,8 @@ target_sources(${LIBNAME}
|
||||
PRIVATE
|
||||
src/register_types.cpp
|
||||
src/register_types.h
|
||||
src/example_class.cpp
|
||||
src/example_class.h
|
||||
src/udpvideostream_class.cpp
|
||||
src/udpvideostream_class.h
|
||||
)
|
||||
|
||||
# Fetch a list of the xml files to use for documentation and add to our target
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
[configuration]
|
||||
|
||||
entry_symbol = "example_library_init"
|
||||
compatibility_minimum = "4.1"
|
||||
reloadable = false
|
||||
|
||||
[libraries]
|
||||
; Relative paths ensure that our GDExtension can be placed anywhere in the project directory.
|
||||
macos.single.debug = "./macos/libEXTENSION-NAME.macos.template_debug.dylib"
|
||||
macos.double.debug = "./macos/libEXTENSION-NAME.macos.template_debug.double.dylib"
|
||||
macos.single.release = "./macos/libEXTENSION-NAME.macos.template_release.dylib"
|
||||
macos.double.release = "./macos/libEXTENSION-NAME.macos.template_release.double.dylib"
|
||||
|
||||
ios.arm64.single.debug = "./ios/libEXTENSION-NAME.ios.template_debug.arm64.dylib"
|
||||
ios.arm64.double.debug = "./ios/libEXTENSION-NAME.ios.template_debug.arm64.double.dylib"
|
||||
ios.arm64.single.release = "./ios/libEXTENSION-NAME.ios.template_release.arm64.dylib"
|
||||
ios.arm64.double.release = "./ios/libEXTENSION-NAME.ios.template_release.arm64.double.dylib"
|
||||
|
||||
windows.x86_32.single.debug = "./windows/EXTENSION-NAME.windows.template_debug.x86_32.dll"
|
||||
windows.x86_32.double.debug = "./windows/EXTENSION-NAME.windows.template_debug.x86_32.double.dll"
|
||||
windows.x86_32.single.release = "./windows/EXTENSION-NAME.windows.template_release.x86_32.dll"
|
||||
windows.x86_32.double.release = "./windows/EXTENSION-NAME.windows.template_release.x86_32.double.dll"
|
||||
|
||||
windows.x86_64.single.debug = "./windows/EXTENSION-NAME.windows.template_debug.x86_64.dll"
|
||||
windows.x86_64.double.debug = "./windows/EXTENSION-NAME.windows.template_debug.x86_64.double.dll"
|
||||
windows.x86_64.single.release = "./windows/EXTENSION-NAME.windows.template_release.x86_64.dll"
|
||||
windows.x86_64.double.release = "./windows/EXTENSION-NAME.windows.template_release.x86_64.double.dll"
|
||||
|
||||
linux.x86_64.single.debug = "./linux/libEXTENSION-NAME.linux.template_debug.x86_64.so"
|
||||
linux.x86_64.double.debug = "./linux/libEXTENSION-NAME.linux.template_debug.x86_64.double.so"
|
||||
linux.x86_64.single.release = "./linux/libEXTENSION-NAME.linux.template_release.x86_64.so"
|
||||
linux.x86_64.double.release = "./linux/libEXTENSION-NAME.linux.template_release.x86_64.double.so"
|
||||
|
||||
linux.arm64.single.debug = "./linux/libEXTENSION-NAME.linux.template_debug.arm64.so"
|
||||
linux.arm64.double.debug = "./linux/libEXTENSION-NAME.linux.template_debug.arm64.double.so"
|
||||
linux.arm64.single.release = "./linux/libEXTENSION-NAME.linux.template_release.arm64.so"
|
||||
linux.arm64.double.release = "./linux/libEXTENSION-NAME.linux.template_release.arm64.double.so"
|
||||
|
||||
linux.rv64.single.debug = "./linux/libEXTENSION-NAME.linux.template_debug.rv64.so"
|
||||
linux.rv64.double.debug = "./linux/libEXTENSION-NAME.linux.template_debug.rv64.double.so"
|
||||
linux.rv64.single.release = "./linux/libEXTENSION-NAME.linux.template_release.rv64.so"
|
||||
linux.rv64.double.release = "./linux/libEXTENSION-NAME.linux.template_release.rv64.double.so"
|
||||
|
||||
android.x86_64.single.debug = "./android/libEXTENSION-NAME.android.template_debug.x86_64.so"
|
||||
android.x86_64.double.debug = "./android/libEXTENSION-NAME.android.template_debug.x86_64.double.so"
|
||||
android.x86_64.single.release = "./android/libEXTENSION-NAME.android.template_release.x86_64.so"
|
||||
android.x86_64.double.release = "./android/libEXTENSION-NAME.android.template_release.x86_64.double.so"
|
||||
|
||||
android.arm64.single.debug = "./android/libEXTENSION-NAME.android.template_debug.arm64.so"
|
||||
android.arm64.double.debug = "./android/libEXTENSION-NAME.android.template_debug.arm64.double.so"
|
||||
android.arm64.single.release = "./android/libEXTENSION-NAME.android.template_release.arm64.so"
|
||||
android.arm64.double.release = "./android/libEXTENSION-NAME.android.template_release.arm64.double.so"
|
||||
|
||||
web.wasm32.single.debug = "./web/libEXTENSION-NAME.web.template_debug.wasm32.nothreads.wasm"
|
||||
web.wasm32.double.debug = "./web/libEXTENSION-NAME.web.template_debug.wasm32.double.nothreads.wasm"
|
||||
web.wasm32.single.release = "./web/libEXTENSION-NAME.web.template_release.wasm32.nothreads.wasm"
|
||||
web.wasm32.double.release = "./web/libEXTENSION-NAME.web.template_release.wasm32.double.nothreads.wasm"
|
||||
6
project/bin/gdvapi.gdextension
Normal file
6
project/bin/gdvapi.gdextension
Normal file
@@ -0,0 +1,6 @@
|
||||
[configuration]
|
||||
entry_symbol = "gdvapi_library_init"
|
||||
compatibility_minimum = "4.7"
|
||||
|
||||
[libraries]
|
||||
linux.x86_64 = "res://bin/linux/gdvapi.linux.template_debug.x86_64.so"
|
||||
1
project/bin/gdvapi.gdextension.uid
Normal file
1
project/bin/gdvapi.gdextension.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://vgmwthvwcljf
|
||||
@@ -2,5 +2,4 @@ extends Node
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
var example := ExampleClass.new()
|
||||
example.print_type(example)
|
||||
$UDPVideoStream.begin("localhost:1000")
|
||||
|
||||
1
project/example.gd.uid
Normal file
1
project/example.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bkwk40ybs8kgm
|
||||
@@ -1,6 +1,8 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://dh0oj81pufivs"]
|
||||
[gd_scene format=3 uid="uid://dh0oj81pufivs"]
|
||||
|
||||
[ext_resource type="Script" path="res://example.gd" id="1_jdh55"]
|
||||
[ext_resource type="Script" uid="uid://bkwk40ybs8kgm" path="res://example.gd" id="1_jdh55"]
|
||||
|
||||
[node name="Node" type="Node"]
|
||||
[node name="Node" type="Node" unique_id=2080300232]
|
||||
script = ExtResource("1_jdh55")
|
||||
|
||||
[node name="UDPVideoStream" type="UDPVideoStream" parent="." unique_id=270982386]
|
||||
|
||||
@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.cte
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
@@ -25,6 +27,10 @@ mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
|
||||
@@ -8,8 +8,13 @@
|
||||
|
||||
config_version=5
|
||||
|
||||
[animation]
|
||||
|
||||
compatibility/default_parent_skeleton_in_mesh_instance_3d=true
|
||||
|
||||
[application]
|
||||
|
||||
config/name="godot cpp template"
|
||||
config/features=PackedStringArray("4.1", "Forward Plus")
|
||||
run/main_scene="uid://dh0oj81pufivs"
|
||||
config/features=PackedStringArray("4.7", "Forward Plus")
|
||||
config/icon="res://icon.svg"
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
#include "example_class.h"
|
||||
|
||||
void ExampleClass::_bind_methods() {
|
||||
godot::ClassDB::bind_method(D_METHOD("print_type", "variant"), &ExampleClass::print_type);
|
||||
}
|
||||
|
||||
void ExampleClass::print_type(const Variant &p_variant) const {
|
||||
print_line(vformat("Type: %d", p_variant.get_type()));
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "godot_cpp/classes/ref_counted.hpp"
|
||||
#include "godot_cpp/classes/wrapped.hpp"
|
||||
#include "godot_cpp/variant/variant.hpp"
|
||||
|
||||
using namespace godot;
|
||||
|
||||
class ExampleClass : public RefCounted {
|
||||
GDCLASS(ExampleClass, RefCounted)
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
ExampleClass() = default;
|
||||
~ExampleClass() override = default;
|
||||
|
||||
void print_type(const Variant &p_variant) const;
|
||||
};
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <godot_cpp/core/defs.hpp>
|
||||
#include <godot_cpp/godot.hpp>
|
||||
|
||||
#include "example_class.h"
|
||||
#include "udpvideostream_class.h"
|
||||
|
||||
using namespace godot;
|
||||
|
||||
@@ -14,7 +14,7 @@ void initialize_gdextension_types(ModuleInitializationLevel p_level)
|
||||
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
|
||||
return;
|
||||
}
|
||||
GDREGISTER_CLASS(ExampleClass);
|
||||
GDREGISTER_CLASS(UDPVideoStream);
|
||||
}
|
||||
|
||||
void uninitialize_gdextension_types(ModuleInitializationLevel p_level) {
|
||||
@@ -26,7 +26,7 @@ void uninitialize_gdextension_types(ModuleInitializationLevel p_level) {
|
||||
extern "C"
|
||||
{
|
||||
// Initialization
|
||||
GDExtensionBool GDE_EXPORT example_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization)
|
||||
GDExtensionBool GDE_EXPORT gdvapi_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization)
|
||||
{
|
||||
GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization);
|
||||
init_obj.register_initializer(initialize_gdextension_types);
|
||||
@@ -35,4 +35,4 @@ extern "C"
|
||||
|
||||
return init_obj.init();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
97
src/udpvideostream_class.cpp
Normal file
97
src/udpvideostream_class.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
#include "udpvideostream_class.h"
|
||||
#include "godot_cpp/classes/rendering_server.hpp"
|
||||
#include "godot_cpp/classes/rendering_device.hpp"
|
||||
#include "godot_cpp/classes/rd_texture_format.hpp"
|
||||
#include "godot_cpp/classes/rd_texture_view.hpp"
|
||||
|
||||
|
||||
using namespace godot;
|
||||
|
||||
void UDPVideoStream::_bind_methods() {
|
||||
godot::ClassDB::bind_method(D_METHOD("begin", "variant"), &UDPVideoStream::begin);
|
||||
}
|
||||
|
||||
void UDPVideoStream::begin(const Variant &source) const {
|
||||
print_line(vformat("[gdvapi] begin stream at %s", source.stringify()));
|
||||
}
|
||||
|
||||
UDPVideoStream::~UDPVideoStream() {
|
||||
cleanup();
|
||||
}
|
||||
|
||||
void UDPVideoStream::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_POST_ENTER_TREE: {
|
||||
texture_init();
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
cleanup();
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void UDPVideoStream::texture_init() {
|
||||
RenderingDevice *rd = RenderingServer::get_singleton()->get_rendering_device();
|
||||
if (!rd) {
|
||||
UtilityFunctions::printerr("Vulkan RenderingDevice is not available!");
|
||||
return;
|
||||
}
|
||||
|
||||
int width = 256;
|
||||
int height = 256;
|
||||
|
||||
Ref<RDTextureFormat> format;
|
||||
format.instantiate();
|
||||
format->set_texture_type(RenderingDevice::TEXTURE_TYPE_2D);
|
||||
format->set_format(RenderingDevice::DATA_FORMAT_R8G8B8A8_UNORM);
|
||||
format->set_width(width);
|
||||
format->set_height(height);
|
||||
format->set_depth(1);
|
||||
format->set_array_layers(1);
|
||||
format->set_mipmaps(1);
|
||||
format->set_usage_bits(RenderingDevice::TEXTURE_USAGE_SAMPLING_BIT |
|
||||
RenderingDevice::TEXTURE_USAGE_CAN_UPDATE_BIT);
|
||||
|
||||
PackedByteArray byte_array;
|
||||
byte_array.resize(width * height * 4);
|
||||
for (int i = 0; i < byte_array.size(); i += 4) {
|
||||
byte_array[i] = 0;
|
||||
byte_array[i + 1] = 0;
|
||||
byte_array[i + 2] = 255;
|
||||
byte_array[i + 3] = 255;
|
||||
}
|
||||
|
||||
TypedArray<PackedByteArray> data;
|
||||
data.push_back(byte_array);
|
||||
|
||||
Ref<RDTextureView> view;
|
||||
view.instantiate();
|
||||
|
||||
texture_rd_rid = rd->texture_create(format, view, data);
|
||||
|
||||
if (texture_rd_rid.is_valid()) {
|
||||
godot_texture.instantiate();
|
||||
godot_texture->set_texture_rd_rid(texture_rd_rid);
|
||||
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
void UDPVideoStream::cleanup() {
|
||||
RenderingDevice *rd = RenderingServer::get_singleton()->get_rendering_device();
|
||||
|
||||
godot_texture.unref();
|
||||
|
||||
if (rd && texture_rd_rid.is_valid()) {
|
||||
rd->free_rid(texture_rd_rid);
|
||||
texture_rd_rid = RID();
|
||||
}
|
||||
}
|
||||
|
||||
void UDPVideoStream::_draw() {
|
||||
if (godot_texture.is_valid() && godot_texture->get_texture_rd_rid().is_valid()) {
|
||||
draw_texture(godot_texture, Point2(0, 0));
|
||||
}
|
||||
}
|
||||
32
src/udpvideostream_class.h
Normal file
32
src/udpvideostream_class.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include "godot_cpp/classes/control.hpp"
|
||||
#include "godot_cpp/classes/wrapped.hpp"
|
||||
#include "godot_cpp/variant/variant.hpp"
|
||||
#include "godot_cpp/classes/rendering_device.hpp"
|
||||
#include "godot_cpp/classes/texture2drd.hpp"
|
||||
|
||||
using namespace godot;
|
||||
|
||||
class UDPVideoStream : public Control {
|
||||
GDCLASS(UDPVideoStream, Control)
|
||||
|
||||
private:
|
||||
RID texture_rd_rid;
|
||||
Ref<Texture2DRD> godot_texture;
|
||||
|
||||
void cleanup();
|
||||
void texture_init();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
UDPVideoStream() = default;
|
||||
~UDPVideoStream() override;
|
||||
|
||||
void begin(const Variant &source) const;
|
||||
|
||||
void _notification(int p_what);
|
||||
virtual void _draw() override;
|
||||
};
|
||||
Reference in New Issue
Block a user