180 lines
5.5 KiB
C++
180 lines
5.5 KiB
C++
/******************************************************************************
|
|
QtAV: Media play library based on Qt and FFmpeg
|
|
Copyright (C) 2012-2016 Wang Bin <wbsecg1@gmail.com>
|
|
|
|
* This file is part of QtAV (from 2016)
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
******************************************************************************/
|
|
#include "gl_api.h"
|
|
#include "OpenGLHelper.h"
|
|
|
|
namespace FAV {
|
|
typedef void *(*GetProcAddress_t)(const char *);
|
|
static GetProcAddress_t sGetProcAddress;
|
|
|
|
void* GetProcAddress_Qt(const char *name)
|
|
{
|
|
if (!QOpenGLContext::currentContext())
|
|
return 0;
|
|
void* p = (void*)QOpenGLContext::currentContext()->getProcAddress(QByteArray((const char*)name));
|
|
if (!p) {
|
|
#if defined(Q_OS_WIN) && defined(QT_OPENGL_DYNAMIC)
|
|
HMODULE handle = (HMODULE)QOpenGLContext::openGLModuleHandle();
|
|
if (handle)
|
|
p = (void*)GetProcAddress(handle, name);
|
|
#endif
|
|
}
|
|
//fallback to QOpenGLFunctions_1_0?
|
|
return p;
|
|
}
|
|
|
|
static void* GetProcAddressWithExt(GetProcAddress_t get, const char *name)
|
|
{
|
|
void* fp = get(name);
|
|
if (fp)
|
|
return fp;
|
|
static const char *ext[] = {
|
|
"ARB", "OES", "EXT", "ANGLE", "NV" //TODO: MESA, INTEL?
|
|
#ifdef __APPLE__
|
|
, "APPLE"
|
|
#endif
|
|
, NULL
|
|
};
|
|
char f[512];
|
|
memcpy(f, name, strlen(name));
|
|
char* const p = f + strlen(name);
|
|
for (int i = 0; ext[i]; ++i) {
|
|
memcpy(p, ext[i], sizeof(ext[i]) + 1); //copy trail '\0'
|
|
fp = get(f);
|
|
if (fp) {
|
|
printf("extension resolved: %s", f);
|
|
return fp;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static void* GetProcAddressDefault(const char *name)
|
|
{
|
|
return GetProcAddressWithExt(GetProcAddress_Qt, name);
|
|
}
|
|
|
|
#ifdef QT_OPENGL_DYNAMIC
|
|
#define GETPROCADDRESS_RESOLVE
|
|
// GL_RESOLVE_ES_X_X will link to lib or use getProcAddress
|
|
#define GL_RESOLVE_ES_2_0(name) GL_RESOLVE(name)
|
|
#define GL_RESOLVE_ES_3_0(name) GL_RESOLVE(name)
|
|
#define GL_RESOLVE_ES_3_1(name) GL_RESOLVE(name)
|
|
#else
|
|
#ifdef GL_ES_VERSION_2_0
|
|
#define GL_RESOLVE_ES_2_0(name) GL_RESOLVE(name)
|
|
#define GL_RESOLVE_ES_3_0(name) GL_RESOLVE_EXT(name)
|
|
#define GL_RESOLVE_ES_3_1(name) GL_RESOLVE_EXT(name)
|
|
#elif GL_ES_VERSION_3_0
|
|
#define GL_RESOLVE_ES_2_0(name) GL_RESOLVE(name)
|
|
#define GL_RESOLVE_ES_3_0(name) GL_RESOLVE(name)
|
|
#define GL_RESOLVE_ES_3_1(name) GL_RESOLVE_NONE(name) //gl3ext is empty
|
|
#elif GL_ES_VERSION_3_1
|
|
#define GL_RESOLVE_ES_2_0(name) GL_RESOLVE(name)
|
|
#define GL_RESOLVE_ES_3_0(name) GL_RESOLVE(name)
|
|
#define GL_RESOLVE_ES_3_1(name) GL_RESOLVE(name)
|
|
#else
|
|
#define GETPROCADDRESS_RESOLVE
|
|
// GL_RESOLVE_ES_X_X will link to lib or use getProcAddress
|
|
#define GL_RESOLVE_ES_2_0(name) GL_RESOLVE(name)
|
|
#define GL_RESOLVE_ES_3_0(name) GL_RESOLVE(name)
|
|
#define GL_RESOLVE_ES_3_1(name) GL_RESOLVE(name)
|
|
#endif
|
|
#endif //QT_OPENGL_DYNAMIC
|
|
|
|
|
|
#define GL_RESOLVE_NONE(name) do { name = NULL;}while(0)
|
|
#define GL_RESOLVE_EXT(name) do {\
|
|
void** fp = (void**)(&name); \
|
|
*fp = GetProcAddressDefault("gl" # name); \
|
|
} while(0)
|
|
#ifdef GETPROCADDRESS_RESOLVE
|
|
#define GL_RESOLVE(name) GL_RESOLVE_EXT(name)
|
|
#else
|
|
#define GL_RESOLVE(name) do {\
|
|
name = ::gl##name; \
|
|
} while(0)
|
|
#endif
|
|
|
|
#define WGL_RESOLVE(name) do {\
|
|
void** fp = (void**)(&name); \
|
|
*fp = sGetProcAddress("wgl" # name); \
|
|
} while(0)
|
|
|
|
void api::resolve()
|
|
{
|
|
//memset(g, 0, sizeof(g));
|
|
sGetProcAddress = GetProcAddressDefault;
|
|
GL_RESOLVE(GetString);
|
|
GL_RESOLVE(GetError);
|
|
GL_RESOLVE(ActiveTexture);
|
|
GL_RESOLVE(BindFramebuffer);
|
|
GL_RESOLVE(GetUniformLocation);
|
|
GL_RESOLVE(Uniform1f);
|
|
GL_RESOLVE(Uniform2f);
|
|
GL_RESOLVE(Uniform3f);
|
|
GL_RESOLVE(Uniform4f);
|
|
GL_RESOLVE(Uniform1fv);
|
|
GL_RESOLVE(Uniform2fv);
|
|
GL_RESOLVE(Uniform3fv);
|
|
GL_RESOLVE(Uniform4fv);
|
|
GL_RESOLVE(Uniform1iv);
|
|
GL_RESOLVE(Uniform2iv);
|
|
GL_RESOLVE(Uniform3iv);
|
|
GL_RESOLVE(Uniform4iv);
|
|
GL_RESOLVE(UniformMatrix2fv);
|
|
GL_RESOLVE(UniformMatrix3fv);
|
|
GL_RESOLVE(UniformMatrix4fv);
|
|
GL_RESOLVE(BlendFuncSeparate);
|
|
|
|
GL_RESOLVE_ES_3_1(GetTexLevelParameteriv);
|
|
|
|
#ifdef Q_OS_WIN32
|
|
if (!OpenGLHelper::isOpenGLES()) {
|
|
static const char* ext[] = {
|
|
"WGL_NV_DX_interop2",
|
|
"WGL_NV_DX_interop",
|
|
NULL,
|
|
};
|
|
if (OpenGLHelper::hasExtension(ext)) { // TODO: use wgl getprocaddress function (for qt4)
|
|
qDebug("resolving WGL_NV_DX_interop...");
|
|
WGL_RESOLVE(DXSetResourceShareHandleNV);
|
|
WGL_RESOLVE(DXOpenDeviceNV);
|
|
WGL_RESOLVE(DXCloseDeviceNV);
|
|
WGL_RESOLVE(DXRegisterObjectNV);
|
|
WGL_RESOLVE(DXUnregisterObjectNV);
|
|
WGL_RESOLVE(DXObjectAccessNV);
|
|
WGL_RESOLVE(DXLockObjectsNV);
|
|
WGL_RESOLVE(DXUnlockObjectsNV);
|
|
}
|
|
}
|
|
#endif //Q_OS_WIN32
|
|
}
|
|
|
|
api& gl() {
|
|
static api g;
|
|
if (!sGetProcAddress) {
|
|
g.resolve();
|
|
}
|
|
return g;
|
|
}
|
|
} //namespace FAV
|