Hi all,
I am writing a VGUI-based application that needs to generate some OpenGL
lists in a subclass of vgui_wrapper_tableau. Actually I follow the
“vgui_adaptor_tableau, basic_manager (subclassing vgui_wrapper_tableau),
vgui_shell_tableau, vgui_viewer2D_tableau, vgui_image_tableau” hierarchy
used by most VGUI examples (e.g. basic_app, xcv).
My problem is that in basic_manager::init, the call to OpenGL function
glGenLists succeeds for some toolkits including mfc (with
argument --mfc-use-gl), glut and win32, but fails for others, namely gtk2
and qt4.
After some analysis, I find the culprit for the failure of glGenLists might
be incorrect setup of OpenGL rendering context (RC). This setup of GL RC is
the work of vgui_foo_adaptor (foo=mfc/gtk/qt/glut/win32). This can be
justified by changing the order the following two lines in function main.
The correct order is:
vgui_window* win = vgui::produce_window(w, h, title);
basic_manager* man = basic_manager::instance();
This is the wrong order that accounts for one reason of the failure of
glGenlists:
basic_manager* man = basic_manager::instance();
vgui_window* win = vgui::produce_window(w, h, title);
Nonetheless, I still could not find out the cause why glGenLists fails when
gtk and qt is used.
When either gtk or qt is used, one interesting observation is that once the
main program window is shown, subsequent calls to glGenLists succeed. As I
am not familiar with gtk or qt technology, I hope someone could kindly give
me some help. I have also written a simple application to illustrate my
issue.
Lianqing Yu
2009/12/29
PS: source code of a test program:
// test/test_gl_list.cpp
// Test if OpenGL lists can be generated during tableau initialization.
// A red triangle should be displayed at the center of the window.
#include <vgui/vgui_wrapper_tableau.h>
#include <vgui/vgui_image_tableau.h>
#include <vgui/vgui_easy2D_tableau.h>
#include <vgui/vgui_viewer2D_tableau.h>
#include <vgui/vgui_shell_tableau.h>
#include <vgui/vgui.h>
#include <vgui/vgui_adaptor.h>
#include <vgui/vgui_window.h>
#ifdef WIN32
#include <windows.h>
#endif
#include <GL/gl.h>
class basic_manager : public vgui_wrapper_tableau
{
public:
~basic_manager() {}
static basic_manager *instance()
{
static basic_manager *instance_ = 0;
if (!instance_) {
instance_ = new basic_manager();
instance_->init();
}
return instance_;
}
void init()
{
vgui_image_tableau_sptr img = vgui_image_tableau_new();
vgui_viewer2D_tableau_sptr viewer = vgui_viewer2D_tableau_new(img);
vgui_shell_tableau_sptr shell = vgui_shell_tableau_new(viewer);
this->add_child(shell);
// Create a OpenGL list.
listName = glGenLists(1);
if ( listName == 0 )
vcl_cerr << "Fail to generate opengl list.\n";
else {
// Create a red triangle
glNewList(listName, GL_COMPILE);
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_TRIANGLES);
glVertex2f(250.0, 100.0);
glVertex2f(400.0, 400.0);
glVertex2f(100.0, 400.0);
glEnd();
glEndList();
}
}
virtual bool handle(vgui_event const &e)
{
//pass the event to the shell
this->child.handle(e);
if ( e.type == vgui_DRAW )
glCallList(listName);
return false;
}
private:
basic_manager() : vgui_wrapper_tableau() {}
GLuint listName;
};
int main(int argc, char** argv)
{
vgui::init(argc, argv);
unsigned w = 512, h = 512;
vcl_string title = "OpenGL List Test";
vgui_window* win = vgui::produce_window(w, h, title);
basic_manager* man = basic_manager::instance();
win->get_adaptor()->set_tableau(man);
win->set_statusbar(true);
win->enable_vscrollbar(true);
win->enable_hscrollbar(true);
win->show();
return vgui::run();
}
|