我试图在我的Windows应用中使用一些OpenGL
要激活gl延伸功能,应该照常执行这些步骤:
以这种方式获取所有需要的地址
PFNGLCOMPILESHADERPROC glCompileShader; glCompileShader =(PFNGLCOMPILESHADERPROC)wglGetProcAddress(" glCompileShader&#34);
右?
确定。首先,我在窗口中有一个简单的openGL功能,而且我刚刚创建了一个单独的窗口类 在那里完成所有子类化以及所有在openGL初始化和绘制的函数。 在同一个类中,我有一长串函数指针作为类数据成员,所以我可以在这个窗口类中使用它们。对于第6步,我创建了一个名为load_glext_functions()的单独函数
所以最后我的课看起来像这样(简化):
{ 上市: HBRUSH brush_background; HWND 的hWnd; HDC 的hDC, hDC_offscreen; HGLRC hGLRC; RECT client_area; 点 PT; GLfloat mesh_color [3], point_color [3];
GLuint
program_id_default,
program_id_lights,
program_id_grid,
program_id_wireframe,
texture_id_fbo_color_ms,
texture_id_fbo_objectid_ms,
texture_id_fbo_objectid,
texture_id_fbo_depth_ms,
texture_id_fbo_depth,
texture_id_default_white;
bool
wireframe_mode,
alt_pressed;
//GLEXT_PROCEDURES
PFNGLCREATESHADERPROC glCreateShader;
PFNGLATTACHSHADERPROC glAttachShader;
PFNGLSHADERSOURCEPROC glShaderSource;
PFNGLCOMPILESHADERPROC glCompileShader;
PFNGLDELETESHADERPROC glDeleteShader;
PFNGLGETSHADERIVPROC glGetShaderiv;
PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
PFNGLCREATEPROGRAMPROC glCreateProgram;
PFNGLUSEPROGRAMPROC glUseProgram;
PFNGLGETPROGRAMIVPROC glGetProgramiv;
PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
//METHODS
Cnerv_window_gl();
~Cnerv_window_gl();
bool init(HINSTANCE hInstance,HWND hParent);
void load_glext_functions();
void draw_mesh(Snerv_viewport_object _display_object);
bool draw_scene();
void draw_viewport();
void create_texture(Cnerv_texture *_texture_handle);
void add_mesh_to_GPU(Cnerv_mesh *mesh_data);
void update_vbo(Cnerv_mesh *_mesh);
void update_texture(Cnerv_texture *_texture_handle);
void init_framebuffer();
void paint();
bool setPFD();
LRESULT CALLBACK wProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK wProc_init_gl(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
};
并且load_glext_function()如下所示:
void Cnerv_window_gl::load_glext_functions()
{
glCompileShader=(PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader");
glAttachShader=(PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader");
glCreateProgram=(PFNGLCREATEPROGRAMPROC)wglGetProcAddress("glCreateProgram");
glCreateShader=(PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader");
glEnableVertexAttribArray=(PFNGLENABLEVERTEXATTRIBARRAYPROC)wglGetProcAddress("glEnableVertexAttribArray");
}
再长一点。
因此,只要我在一个类中使用theese extention函数,就可以了。 现在,如果我想使用面向对象的样式,我需要为其创建单独的类 质地 帧缓冲区 啮合, 等。
并说类Cframebuffer应该拥有它自己的init func,我们应该有glGenFramebuffers()这是扩展名,这个列表可以继续
class Cframebuffer
{
public:
GLuint fbo_id;
void init()
{
glGenFramebuffers(1,&fbo_id);
}
void delete()
{
glDeleteFramebuffers(fbo_id);
}
};
现在。我想把所有这些扩展放在一个单独的类中 像这样
class Cgl_extentions
{
public:
static PFNGLCREATESHADERPROC glCreateShader;
static PFNGLATTACHSHADERPROC glAttachShader;
static PFNGLSHADERSOURCEPROC glShaderSource;
static PFNGLCOMPILESHADERPROC glCompileShader;
static init();
}
其中init看起来像这样
void Cgl_extentions::init()
{
glCompileShader=(PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader");
glAttachShader=(PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader");
glCreateProgram=(PFNGLCREATEPROGRAMPROC)wglGetProcAddress("glCreateProgram");
glCreateShader=(PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader");
glEnableVertexAttribArray=(PFNGLENABLEVERTEXATTRIBARRAYPROC)wglGetProcAddress("glEnableVertexAttribArray");
}
然后我只是在我希望不使用它的地方包含带有扩展类的标题,并将此函数作为类的静态函数来解决 Cgl_extentions :: glGenBuffers().... etc
现在我已经完成了我所描述的内容,但我收到了链接器错误。我试图在我的逻辑中发现一些错误。我做错了什么?
更新:我建议在cpp文件的开头登录theese函数的符号。 它有效。但是这个建议的作者未能解释这个解决方案的内容。 事实上,即使是这个类的普通数据成员也需要这种声明,或者它开始在链接器中提示错误 如果我执行一些注释这里的行是确切的错误字符串
1>Cnerv_GL.obj : error LNK2001: неразрешенный внешний символ ""public: static unsigned int (__cdecl* Cnerv_GL::glCreateShader)(unsigned int)" (?glCreateShader@Cnerv_GL@@2P6AII@ZEA)"
1>Cnerv_window_gl.obj : error LNK2019: ссылка на неразрешенный внешний символ "public: static unsigned int (__cdecl* Cnerv_GL::glCreateShader)(unsigned int)" (?glCreateShader@Cnerv_GL@@2P6AII@ZEA) в функции "public: bool __cdecl Cnerv_window_gl::init(struct HINSTANCE__ *,struct HWND__ *)" (?init@Cnerv_window_gl@@QEAA_NPEAUHINSTANCE__@@PEAUHWND__@@@Z)
1>Cnerv_GL.obj : error LNK2001: неразрешенный внешний символ ""public: static void (__cdecl* Cnerv_GL::glAttachShader)(unsigned int,unsigned int)" (?glAttachShader@Cnerv_GL@@2P6AXII@ZEA)"
1>Cnerv_window_gl.obj : error LNK2019: ссылка на неразрешенный внешний символ "public: static void (__cdecl* Cnerv_GL::glAttachShader)(unsigned int,unsigned int)" (?glAttachShader@Cnerv_GL@@2P6AXII@ZEA) в функции "public: static __int64 __cdecl Cnerv_window_gl::wProc_init_gl(struct HWND__ *,unsigned int,unsigned __int64,__int64)" (?wProc_init_gl@Cnerv_window_gl@@SA_JPEAUHWND__@@I_K_J@Z)
对不起,它是俄语的,但我认为对于所有经验丰富的代码老手来说,这不是问题。)
答案 0 :(得分:1)
使GL函数全局化,至少在渲染代码中,或者如果你想要C ++'ify的话,可以将它们放在GL命名空间中。例如GL::compileShader()
并在加载GL库后初始化。
将GL函数视为任何其他导入库,只需使用非标准导入机制。还可以查看GLEW,这样可以避免担心这样的问题,这样您就可以专注于您要解决的主要问题。
我认为无论您的应用程序大小,复杂程度以及它的架构如何,GL函数指针都需要在渲染后端中具有一些全局可见性,因为所有GL对象类型都使用了一些GL函数。
如果您想继续沿着自己的路径行进,则必须提供有关链接器错误的更多信息。