#include "GlDxInteropExtensions.hpp"

// GL/DX extensions
PFNWGLDXOPENDEVICENVPROC				wglDXOpenDeviceNV = nullptr;
PFNWGLDXREGISTEROBJECTNVPROC			wglDXRegisterObjectNV = nullptr;
PFNWGLDXSETRESOURCESHAREHANDLENVPROC	wglDXSetResourceShareHandleNV = nullptr;
PFNWGLDXLOCKOBJECTSNVPROC				wglDXLockObjectsNV = nullptr;
PFNWGLDXUNLOCKOBJECTSNVPROC				wglDXUnlockObjectsNV = nullptr;
PFNWGLDXCLOSEDEVICENVPROC				wglDXCloseDeviceNV = nullptr;
PFNWGLDXUNREGISTEROBJECTNVPROC			wglDXUnregisterObjectNV = nullptr;

void *GetAnyGLFuncAddress(const char *name)
{
	void *p = (void *)wglGetProcAddress(name);
	if (p == 0 ||
		(p == (void*)0x1) || (p == (void*)0x2) || (p == (void*)0x3) ||
		(p == (void*)-1))

	{
		HMODULE module = LoadLibraryA("opengl32.dll");
		p = (void *)GetProcAddress(module, name);
	}

	return p;
}

bool loadInteropExtensions()
{
	wglDXOpenDeviceNV = (PFNWGLDXOPENDEVICENVPROC)GetAnyGLFuncAddress("wglDXOpenDeviceNV");
	if (!wglDXOpenDeviceNV)
		return false;

	wglDXRegisterObjectNV = (PFNWGLDXREGISTEROBJECTNVPROC)GetAnyGLFuncAddress("wglDXRegisterObjectNV");
	if (!wglDXRegisterObjectNV)
		return false;

	wglDXUnregisterObjectNV = (PFNWGLDXUNREGISTEROBJECTNVPROC)GetAnyGLFuncAddress("wglDXUnregisterObjectNV");
	if (!wglDXUnregisterObjectNV)
		return false;

	wglDXSetResourceShareHandleNV = (PFNWGLDXSETRESOURCESHAREHANDLENVPROC)GetAnyGLFuncAddress("wglDXSetResourceShareHandleNV");
	if (!wglDXSetResourceShareHandleNV)
		return false;

	wglDXLockObjectsNV = (PFNWGLDXLOCKOBJECTSNVPROC)GetAnyGLFuncAddress("wglDXLockObjectsNV");
	if (!wglDXLockObjectsNV)
		return false;

	wglDXUnlockObjectsNV = (PFNWGLDXUNLOCKOBJECTSNVPROC)GetAnyGLFuncAddress("wglDXUnlockObjectsNV");
	if (!wglDXUnlockObjectsNV)
		return false;

	wglDXCloseDeviceNV = (PFNWGLDXCLOSEDEVICENVPROC)GetAnyGLFuncAddress("wglDXCloseDeviceNV");
	if (!wglDXUnlockObjectsNV)
		return false;

	return true;
}