0
\$\begingroup\$

I would like to create a low level native plugin for Unity in C++. The purspose of the plugin would be to create a 2d texture in OpenGL and send its ID to Unity. Below you can examine what I have done so far. The problem is that, when I import the dll plugin and would like to start the unity app with the play button, Unity crashes.

The header:

#pragma once

#include "Unity/IUnityInterface.h"

// Define UnityRenderingExtTexture for returning Unity texture objects
typedef void* UnityRenderingExtTexture;

// Exported functions
extern "C" {
    UnityRenderingExtTexture UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API CreateTextureBuffer(int width, int height);
}

The cpp:

#include "nativepluginForUnityCPlusPlus.h" 
#include "glad/glad.h" 
#include <GLFW/glfw3.h>
#include "stdio.h"
#include "Unity/IUnityInterface.h"
#include "Unity/IUnityGraphics.h"

GLuint textureBuffer; // OpenGL texture buffer ID

// Function to create a buffer for a 2D texture and return a handle
extern "C" UnityRenderingExtTexture UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API CreateTextureBuffer(int width, int height) {
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
    GLFWwindow* window = glfwCreateWindow(1, 1, "Hidden Window", NULL, NULL);

    if (window == NULL)
    {
        glfwTerminate();
        return NULL;
    }
    glfwMakeContextCurrent(window);
    //glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        printf("Failed to initialize GLAD");
        return NULL;
    }

    GLuint textureBuffer; // OpenGL texture buffer ID
    glGenTextures(1, &textureBuffer);
    glBindTexture(GL_TEXTURE_2D, textureBuffer);

    // Set texture parameters and allocate storage
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glBindTexture(GL_TEXTURE_2D, 0);

    glfwTerminate();

    return (UnityRenderingExtTexture)textureBuffer;
}



static IUnityInterfaces* s_UnityInterfaces = NULL;
static IUnityGraphics* s_Graphics = NULL;
static UnityGfxRenderer s_RendererType = kUnityGfxRendererNull;


static void UNITY_INTERFACE_API
OnGraphicsDeviceEvent(UnityGfxDeviceEventType eventType)
{
    switch (eventType)
    {
    case kUnityGfxDeviceEventInitialize:
    {
        s_RendererType = s_Graphics->GetRenderer();
        //TODO: user initialization code
        break;
    }
    case kUnityGfxDeviceEventShutdown:
    {
        s_RendererType = kUnityGfxRendererNull;
        //TODO: user shutdown code
        break;
    }
    case kUnityGfxDeviceEventBeforeReset:
    {
        //TODO: user Direct3D 9 code
        break;
    }
    case kUnityGfxDeviceEventAfterReset:
    {
        //TODO: user Direct3D 9 code
        break;
    }
    };
}


// Unity plugin load event
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
UnityPluginLoad(IUnityInterfaces * unityInterfaces)
{
    s_UnityInterfaces = unityInterfaces;
    s_Graphics = unityInterfaces->Get<IUnityGraphics>();

    s_Graphics->RegisterDeviceEventCallback(OnGraphicsDeviceEvent);

    // Run OnGraphicsDeviceEvent(initialize) manually on plugin load
    // to not miss the event in case the graphics device is already initialized
    OnGraphicsDeviceEvent(kUnityGfxDeviceEventInitialize);
}

// Unity plugin unload event
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
UnityPluginUnload()
{
    s_Graphics->UnregisterDeviceEventCallback(OnGraphicsDeviceEvent);
}

I was taking a look at this example link, which works fine, but this is not as minimalistic as I would like to create. Any help is appreciated!

\$\endgroup\$
2
  • \$\begingroup\$ Do you get any specific error message in the player log or editor log? If you hook a debugger, are you able to catch the exception that causes the crash? \$\endgroup\$
    – DMGregory
    Commented Nov 9, 2023 at 15:44
  • \$\begingroup\$ Are you calling glfwInit() and glfwTerminate() in the right place? Maybe they should be called inside OnGraphicsDeviceEvent() in response to kUnityGfxDeviceEventInitialize and kUnityGfxDeviceEventShutdown? \$\endgroup\$
    – Adam
    Commented Nov 9, 2023 at 20:31

0

You must log in to answer this question.

Browse other questions tagged .