2014-12-24 99 views
0

我试图使用一些OpenGL的在我的Windows应用程序的Open GL extention功能

要激活GL extention功能,theese应采取措施,像往常一样:

  1. 注册窗口类,然后创建它
  2. 设置它的像素格式的窗口
  3. 的GetDC()
  4. wglCreateContext
  5. wglMakeCurrent
  6. 得到所有以这种方式

    PFNGLCOMPILESHADERPROC glCompileShader所需要的地址; glCompileShader =(PFNGLCOMPILESHADERPROC)wglGetProcAddress(“glCompileShader”);

  7. ReleaseDC()

,对吗?

好的。首先,我的窗口中有一个简单的openGL功能,并且我创建了一个单独的窗口类 ,其中包含所有子类,并执行了所有在此处执行的openGL初始化和绘制。 在同一个类中,我有一长串函数指针作为类数据成员,所以我可以在这个窗口类中使用它们。对于第6步我已经创建了一个单独的函数调用load_glext_functions()

所以最后我的课看起来像这样(简化):

{ 市民: HBRUSH brush_background; HWND hWnd; HDC hDC, hDC_offscreen; HGLRC hGLRC; RECT client_area; POINT 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"); 
} 

只是更长的时间。

所以只要我在一个班级内使用扩展功能,每件事都可以。 现在,如果我想使用面向对象的风格,我需要为 纹理 帧缓冲 网, 等创建单独的类..

说类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()....等

现在我已经做了我所描述的,但是我得到了链接错误。我试图在我的逻辑中发现一些错误。我做错了什么?

更新:我被推荐在一个cpp文件的开始处登录这些函数的符号。 它的工作原理。但这个建议的作者没有解释这个解决方案背后发生了什么。 事实上,即使这个类的一个普通的数据成员需要这种声明的或它开始在连接 提示错误,如果我执行在某些行注释这里有精确的错误字符串

1>Cnerv_GL.obj : error LNK2001: неразрешенный внешний символ ""public: static unsigned int (__cdecl* Cnerv_GL::glCreateShader)(unsigned int)" ([email protected][email protected]@[email protected])" 
1>Cnerv_window_gl.obj : error LNK2019: ссылка на неразрешенный внешний символ "public: static unsigned int (__cdecl* Cnerv_GL::glCreateShader)(unsigned int)" ([email protected][email protected]@[email protected]) в функции "public: bool __cdecl Cnerv_window_gl::init(struct HINSTANCE__ *,struct HWND__ *)" ([email protected][email protected]@[email protected]@[email protected]@@Z) 
1>Cnerv_GL.obj : error LNK2001: неразрешенный внешний символ ""public: static void (__cdecl* Cnerv_GL::glAttachShader)(unsigned int,unsigned int)" ([email protected][email protected]@[email protected])" 
1>Cnerv_window_gl.obj : error LNK2019: ссылка на неразрешенный внешний символ "public: static void (__cdecl* Cnerv_GL::glAttachShader)(unsigned int,unsigned int)" ([email protected][email protected]@[email protected]) в функции "public: static __int64 __cdecl Cnerv_window_gl::wProc_init_gl(struct HWND__ *,unsigned int,unsigned __int64,__int64)" ([email protected][email protected]@[email protected]@[email protected]) 

对不起,这是在俄罗斯不过,我想在座的各位风化的代码老兵,这不是一个问题。) enter image description here enter image description here

回答

1

充分利用GL函数全局,至少在你的渲染代码,或者把它们放在一个GL命名空间,如果你想到C++'ify的一切。例如GL::compileShader()并在加载GL库后进行初始化。

想象GL函数就像任何其他导入的库一样,只是使用非标准的导入机制。还可以查看GLEW,它可以帮助您避免担心类似的情况,以便您可以专注于您尝试解决的主要问题。

我认为,无论您的应用程序大小,复杂程度和结构如何,GL函数指针都需要一些全局可见性在您的渲染后端,因为某些GL函数被所有GL对象类型使用。

如果你想继续走自己的路,你将不得不提供更多关于链接器错误的信息。

+0

感谢您的回答。那么你认为我应该把他们带出课堂,并宣布全球?我应该怎样做?在一个单独的文件?我在制作好的建筑方面经验不足,所以我要求提供更多关于这个主题的细节。另外,请检查我的问题更新。它被附加到它的末尾 – Antiusninja

+0

良好的体系结构带有经验。随着时间的推移,你将从错误中学习,并回顾代码并思考“我在做什么?!”我将它们放在一个单独的文件中,并引入一个使用名称空间而不是静态类的新概念。 – djgandy