dam*_*911 4 opengl opengl-extensions
当我发现以下代码及其许多变体产生非空内存地址时,我感到非常惊讶.我尝试的变化包括:
glXGetProcAddressARB而不是glXGetProcAddress.使用GLFW提供的跨平台替代方案:glfwGetProcAddress.
#include <GL/glx.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
void *ptr;
ptr = glXGetProcAddress((const GLubyte *)"glottis");
printf("ptr: %x\n", ptr);
return 0;
}
Run Code Online (Sandbox Code Playgroud)程序是用-lGL(并-lglfw在需要时)编译的,没有警告也没有错误.
获得的唯一途径0输出的NULL指针,是通过询问他的名字不启动函数的地址gl,例如manny.
我对此行为感到非常惊讶,因为glottis并且manny应该同样不存在,并且我希望两者都产生一个NULL指针.
这是glXGetProcAddress文档的摘录.
笔记
如果在被查询的实现中没有支持请求的函数,则返回NULL指针.
由于在查询时可能未加载库,因此GLU函数不可查询.
那么,从正确的角度来看,您观察到的行为是合规的.您不能断定(或其他)的非NULL返回值glXGetProcAddress意味着函数存在或可以使用.您必须始终查询扩展字符串.尝试获取未由扩展字符串公布的函数的函数指针(或其上下文的核心GL版本所暗示的存在)将在概念上是未定义的行为.
您确实引用了参考页面glXGetProcAddress.不幸的是,那些参考页面是不正确的,不完整的,有时甚至是错误的.在这种情况下,措辞至少是不幸的.
我一般建议使用官方规范查找此类详细信息.在这种情况下,GLX 1.4规范将是相关文档.第3.3.12节"获取扩展函数指针"说明了这一点glXGetProcAddress(强调我的):
返回值
NULL表示实现不存在指定的函数.非
NULL返回值glXGetProcAddress不保证在运行时实际支持扩展函数.客户端还必须查询glGetString(GL_EXTENSIONS)或glXQueryExtensionsString确定特定上下文是否支持扩展. [...]
glXGetProcAddress可以查询以下所有功能:
- 实现支持的所有GL和GLX扩展函数(当前上下文是否支持这些扩展).
- GL和GLX中的所有核心(非扩展)功能从版本1.0到包括实现支持的那些规范的版本(由查询
glGetString(GL_VERSION)和glXQueryVersion查询确定).
看起来Mesa3D实现实际上能够为每个查询函数动态生成一些存根gl.
查看当前版本/src/mapi/glapi/glapi_getproc.c显示的功能是_glapi_get_proc_address()这样做的:
/**
* Return pointer to the named function. If the function name isn't found
* in the name of static functions, try generating a new API entrypoint on
* the fly with assembly language.
*/
_glapi_proc
_glapi_get_proc_address(const char *funcName)
{
_glapi_proc func;
struct _glapi_function * entry;
init_glapi_relocs_once();
#ifdef MANGLE
/* skip the prefix on the name */
if (funcName[1] != 'g' || funcName[2] != 'l')
return NULL;
#else
if (funcName[0] != 'g' || funcName[1] != 'l')
return NULL;
#endif
/* search extension functions first */
func = get_extension_proc_address(funcName);
if (func)
return func;
/* search static functions */
func = get_static_proc_address(funcName);
if (func)
return func;
/* generate entrypoint, dispatch offset must be filled in by the driver */
entry = add_function_name(funcName);
if (entry == NULL)
return NULL;
return entry->dispatch_stub;
}
Run Code Online (Sandbox Code Playgroud)
所以它实际上会检查gl前缀,如果该函数未知,它会为它动态创建一个存根.稍后,当加载hw后端驱动程序时,它可能会注册gl函数,如果为其提供实现,则存根代码会将调用转发给驱动程序.
| 归档时间: |
|
| 查看次数: |
652 次 |
| 最近记录: |