Code Monkey home page Code Monkey logo

nativerenderingplugin's Introduction

Native code (C++) rendering plugin example for Unity

This sample demonstrates how to render and do other graphics related things from a C++ plugin, via a native plugin interface.

Unity versions:

  • 2023.1+ use tip of default branch.

The plugin itself does very few things:

  • Demonstrates basic plumbing. How to initialize the graphics API, and how calls from Unity into plugin are made.
  • Draws a triangle. A single colored rotating triangle in the middle of the screen. For each backend API, this shows bare basics of how to setup vertex data, setup some shaders or render states, and do a draw call.
  • Changes Unity texture data. Unity side passes a texture into the plugin, and the code changes the pixels of it each frame, with an animated "plasma" pattern. This demonstrates how to work with Texture.GetNativeTexturePtr.
  • Changes Unity mesh vertex data. Unity side passes a vertex buffer into the plugin, and the code changes the vertices each frame, with an animated "heightfield" pattern. This demonstrates how to work with Mesh.GetNativeVertexBufferPtr.

Native code rendering is implemented for several platforms and graphics APIs:

  • Windows (D3D11, D3D12, OpenGL, Vulkan)
    • Note that Vulkan and DX12 are not compiled in by default
    • Vulkan requires Vulkan SDK; enable it by editing #define SUPPORT_VULKAN 0 to 1 under UNITY_WIN clause in PlatformBase.h
    • DX12 requires additional header files (see on github or nuget package); enable it by editing #define SUPPORT_D3D12 0 to 1 under UNITY_WIN clause in PlatformBase.h
  • macOS (Metal, OpenGL)
  • Linux (OpenGL, Vulkan)
  • Windows Store aka UWP (D3D11, D3D12)
  • WebGL (OpenGL ES)
  • Android (OpenGL ES, Vulkan)
  • iOS/tvOS (Metal; Simulator is supported if you use unity 2020+ and XCode 11+)
  • EmbeddedLinux (OpenGL, Open GLES)
  • ...more platforms might be coming soon, we just did not get around to adding project files yet.

Code is organized as follows:

  • PluginSource is source code & IDE project files for the C++ plugin.
    • source: The source code itself. RenderingPlugin.cpp is the main logic, RenderAPI*.* files contain rendering implementations for different APIs.
    • projects/VisualStudio2022: Visual Studio 2022 project files for regular Windows plugin
    • projects/UWPVisualStudio2022: Visual Studio 2022 project files for Windows Store (UWP) plugin
    • projects/Xcode: Apple Xcode project file for Mac OS X plugin, Xcode 10.3 on macOS 10.14 was tested
    • projects/GNUMake: Makefile for Linux
    • projects/EmbeddedLinux: Windows .bat files to build plugins for different architectures
  • UnityProject is the Unity (2023.1.15f1 was tested) project.
    • Single scene that contains the plugin sample scene.

What license are the graphics samples shipped under?

Just like with most other samples, the license is MIT/X11.

nativerenderingplugin's People

Contributors

aleksis-karastie avatar alexey-unity avatar aras-p avatar borisshir avatar brice-gros avatar graphinenicolas avatar hkr avatar matas-tunkevicius avatar n7rx avatar tak avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nativerenderingplugin's Issues

No REAL Documentation?

Since info provided here and at:

https://docs.unity3d.com/Manual/NativePluginInterface.html

is extremely scarce I started a thread at Unity forum:

https://forum.unity.com/threads/native-plugin-documentation-is-lacking.1220007/

Is IUnityInterface actually meant to be used at any professional capacity or was it meant for enthusiast to try and deduce everything from header files and very simple examples?

At one point in the Vulkan example it says:

// can't use GPU transfer here because is not marked as transfer src

No part of the documentations actually mentions what mode of access is supported by all the different resources in all the APIs (dx11, dx12, vulkan etc). Are people just supposed to experiment and see what won't crash? Is it even possible to access any kind of Debug Layers when working on the plugin to receive any meaningful feedback?

I don't expect any replies but hope this post will help other devs to get an idea of what they are getting into.

Multisamples issues in Vulkan

In Vulkan when creating pipelines, the sample count must be indicated in VkPipelineMultisampleStateCreateInfo. The pipeline can't be later used with a rendertarget with a different sample count.

A native plugin doesn't receive information about the sample count of the current active render pass. I think this could be added to UnityVulkanRecordingState.

Note that the Vulkan example provided in this repository has hardcoded the sample count and doesn't work with cameras using MSAA.

Plugin Load on Startup

I've recently encountered an issue with loading Native Rendering Plugins in order to intercept vkCreateInstance. If I enable "Load on Startup" I can intercept this in the Unity Editor, but built applications load the plugin after Vulkan Instance is created. I'm running Linux and haven't tested this on Windows.

Is this intended functionality? If not, how do I force builds to load a Native Rendering Plugin before Vulkan Instance is created?

GNU makefile error

I run make in the GNU folder and got errors--Undefined symbols for architecture x86_64. Is there any error in the makefile?

Modifying vertex buffer on WebGL is disabled

Hi, I'm trying to run the plugin sample under WebGL. It works fine in Editor, but the mesh is completely flat in web.

Looking at the code, it seems that modifying the mesh was intentionally disabled for WebGL.

void* RenderAPI_OpenGLCoreES::BeginModifyVertexBuffer(void* bufferHandle, size_t* outBufferSize)
{
# if SUPPORT_OPENGL_ES
return 0;
# else
glBindBuffer(GL_ARRAY_BUFFER, (GLuint)(size_t)bufferHandle);
GLint size = 0;
glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
*outBufferSize = size;
void* mapped = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
return mapped;
# endif
}

When removing the check on SUPPORT_OPENGL_ES, I get the following error when building from Unity :

'GL_WRITE_ONLY' is undefined

image

Native Plugin crash on Windows using OpenGL ES 3

It crashes in function static GLuint CreateShader(GLenum type, const char* sourceText) line 125 (GLuint ret = glCreateShader(type);
with:

Exception thrown at 0x0000000000000000 in Unity.exe: 0xC0000005: Access violation executing location 0x0000000000000000.

PC running Windows 11 (10.0.22000.556).
We are using Unity 2021.3.1f1.

Should it work or isn't it meant to work with that version of OpenGL in Windows platform?

Can't work properly in Android

I have build this repository with Unity2019.2, targeting iPhone and Android.

capture-2

iPhone8, iOS 13.6 works successfully.
But Android9 (LG V30+) can't work properly.

I tried several Graphics APIs, such as Vulkan, OpenGLES2, OpenGLES3. But all can't work.

Please let me know if you have good idea.

How does Vulkan API interception work before VkInstance and VkDevice creating and after that?

In my test, I found that the intercept of vkCmdBeginRenderPass by Hook_vkCmdBeginRenderPass in function [ ProcessDeviceEvent ] didn't work in Editor mode.
image

I also intercepted vkCreatInstance in function [ ProcessDeviceEvent ] and it didn't work.

However, if I intercept above APIs in function [ Hook_vkGetInstanceProcAddr ], everything works well.
image

I think I could say that interception in function [ Hook_vkGetInstanceProcAddr ] works definitely .
But when does interception in function [ ProcessDeviceEvent ] work?

Question about vertex buffer layout

I was wondering if the vertex buffer layout is always the same from Unity 2018.4 with DirectX 11 ?

You are using this structure :

struct MeshVertex
{
	float pos[3];
	float normal[3];
	float color[4];
	float uv[2];
};

But let say I just want to use pos and color attributes from my shaders, could I use directly the structure below to fill my ID3D11Buffer ?

struct MeshVertex
{
	float pos[3];
	float color[4];
};

Then before calling the native plugin I could just initialize the mesh like that

m_meshFilter = GetComponent<MeshFilter>();
m_meshFilter.mesh = new Mesh();
m_meshFilter.mesh.indexFormat = IndexFormat.UInt32;
m_meshFilter.mesh.vertices = new Vector3[100000];
m_meshFilter.mesh.colors = new Color[100000];

Also, other question : Do I really need to call MarkDynamic() on the mesh instance if I only set the vertex buffer once during the game ?

Thank you.

Apple Silicon and Unity 2021.3.8f1 - DllNotFoundException: RenderingPlugin assembly:<unknown assembly> type:<unknown type> member:(null)

I can't get the plugin to load on Apple Silicon Unity:

arth@mbp: Plugins % lipo -i RenderingPlugin.dylib                                   
Architectures in the fat file: RenderingPlugin.dylib are: x86_64 arm64

I also tried with the .bundle instead of a dylib but no help. I had to remove the VALID_ARCHS user define from the xcode project in order to get arm64 into it, but whatever I do it is not loaded.

Am I missing something here?

Not working with Vulkan

On Windows this plugin does not work with Vulkan. When changing the Player to use Vulkan no rendering happens from the plugin. Have tried rolling back the plugin to before VulkanV2 change, but no improvements. Have tried installing multiple versions of the Unity Editor, but no improvements.

OpenGL not working

Hello,

I am trying to run my C++ 3D game in Unity using native plugin. The game is 32-bit and uses OpenGL. I commented out directX defines in PlatformBase.h. And the plugin doesn't work (no triangle drawn). My OS is Windows 7, Unity version - 5.6.7f1.

Question on CreateRenderAPI

Sorry for bothering you guys, but I really would like to understand one thing.

Can somebody explain to me why RegisterPlugin() is called only for WEBGL?

#if UNITY_WEBGL && !UNITY_EDITOR
RegisterPlugin();

I don't quite understand from the code how OnGraphicsDeviceEvent (which creates an instance of the RenderAPI) gets called.

In other words, when not using UNITY_WEBGL how does CreateRenderAPI gets called?

s_CurrentAPI = CreateRenderAPI(s_DeviceType);

I know that I am missing something, since the code seems to work just fine.

Thank you very much.

Windows Setup Guide

Hi there. I am a newbie in unity and want to render some graphics using unity. can you please point the way to a guide to setup this plugin with my VS2015 C++ project?

Does AccessRenderBufferTexture of Vulkan Plugin API can transition image layout?

UnityVulkanImage image;
    if (!m_UnityVulkan->AccessRenderBufferTexture((UnityRenderBuffer)data->colorBuffer, UnityVulkanWholeImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
        VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT, kUnityVulkanResourceAccess_PipelineBarrier, &image))
    {
        UnityLog("failed to access rendertexture color buffer");
        return;
    }

after calling the API, I print the image.layout, it's VK_IMAGE_LAYOUT_UNDEFINED type instead of VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL. Because I want to sample the texture, so the image layout out must be VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL.
Do I need to transition image layout manully?

Can't get android to work with Vulkan

for some reason it can't get the interface for Vulkan to work on Android. I've tried several variations, 32 bit or 64 bit, Unity 2018.4 or 2020.1, Mono or il2cpp, changing min android version to 19 or 26, but the demo just crashes. Works fine for OpenGL

When I step through UnityPluginLoad
s_Graphics is set to a valid interface for IUnityGraphics
s_Graphics->GetRenderer() is returning kUnityGfxRendererVulkan as expected
but unityInterfaces->Get<IUnityGraphicsVulkan>() is returning NULL
I've checked, it's not a matter of timing, because even if I call s_UnityInterfaces->Get<IUnityGraphicsVulkan>() at a later frame, it's still 0

The only thing I can think of, is the GUID is incorrect in IUnityGraphicsVulkan
Can you confirm at least that it is as stated in the header file
UNITY_REGISTER_INTERFACE_GUID(0x95355348d4ef4e11ULL, 0x9789313dfcffcc87ULL, IUnityGraphicsVulkan)
as I can't think of a way to confirm it myself, as I don't think you can get a list of registered interfaces.
I know it must be possible to get a working interface to Unity Vulkan from NDK, as I have seen it in other projects. We have developed a plugin for Unity, and since the default renderer for 2019 + is now Vulkan, rather than OpenGL, we can't really insist on people using OpenGL for their projects.
Any hints on how to fix this, would be appreciated.
James

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.