iva*_*ult 5 c++ opengl templates
例如,让我有一个标题#include <GL/gl.h>.它包含OpenGL API函数的子集.我需要这样的东西:
static_assert(has_glDrawArraysIndirect::value, "There is no glDrawArraysIndirect");
Run Code Online (Sandbox Code Playgroud)
甚至更好:
PFNGLDRAWARRAYSINSTANCEDPROC ptr_glDrawArraysIndirect = ptr_to_glDrawArraysIndirect::ptr;
Run Code Online (Sandbox Code Playgroud)
当ptr_to_glDrawArraysIndirect::ptr解开,如果它的定义或存根函数指针glDrawArraysIndirect stub_glDrawArraysIndirect否则.
我的目标操作系统非常具体.任何基于链接器的解决方案(如GetProcAddress或dlsym)对我都不起作用,因为没有动态链接器.不止,我的驱动程序没有提供glXGetProcAdrress也没有wglGetProcAddress,基本上没有办法在运行时通过函数名查询指针(实际上,我想实现这样的机制).
有任何想法吗?
这是一个可以在编译时检测它并产生一个布尔值的答案.它的工作原理是在命名空间中创建同名的模板函数,然后在is_defined()函数内部使用该命名空间.如果真实glDrawArraysIndirect()存在,它将优先于模板版本.如果你注释掉glDrawArraysIndirect()底部的静态断言的第一个声明将触发.
#include <type_traits>
enum GLenum {};
void glDrawArraysIndirect(GLenum, const void*);
namespace detail {
struct dummy;
template<typename T>
dummy& glDrawArraysIndirect(T, const void*);
}
constexpr bool is_defined()
{
using namespace detail;
using ftype = decltype(glDrawArraysIndirect(GLenum(), nullptr));
return std::is_same<ftype, void>();
}
static_assert(is_defined(), "not defined");
Run Code Online (Sandbox Code Playgroud)
通过一些调整,您可以将自定义功能作为模板并使用类似的技巧
#include <type_traits>
#include <iostream>
//#define USE_REAL
enum GLenum {TEST};
typedef void (*func_type)(GLenum, const void*);
#ifdef USE_REAL
void glDrawArraysIndirect(GLenum, const void*);
#endif
namespace detail {
struct dummy {};
template<typename T = dummy>
void glDrawArraysIndirect(GLenum, const void*, T = T())
{
std::cout << "In placeholder function" << std::endl;
}
}
void wrapDraw(GLenum x, const void* y)
{
using namespace detail;
glDrawArraysIndirect(x, y);
}
#ifdef USE_REAL
void glDrawArraysIndirect(GLenum, const void*)
{
std::cout << "In real function" << std::endl;
}
#endif
int main()
{
wrapDraw(TEST, nullptr);
}
Run Code Online (Sandbox Code Playgroud)