opengl gpgpu : glew的初始化——不使用glut
在linux平台上使用opengl + cg进行gpu通用编程的时候,glew初始化的问题总是困扰着我。glewInit()成功的条件就是有一个有效的GLXContext!如果想正确得到这个GLXContext就要调用glut里面如下的函数:
glutInit(&argc,argv);
glutCreateWindow("nowindow");
在这两个函数的后面调用glewInit()可以正常初始化,但是有个很讨厌的地方就是:虽然我没有调用glutMainLoop(),但是我的应用程序有一个窗口,那个很猥琐的“nowindow”就会悄悄的弹了出来。这样很影响我的情绪和思路。如果要得到GLXContext必须要建立一个窗口,这个我必须承认。但是:你建了个窗口能不能别show出来啊?我问百度,问必应,中文英文都问了总是得不到想要的答案!终于在google的帮助下我找到了一个论坛,给了我满意的答案!地址:http://www.gpgpu.org/forums/viewtopic.php?p=19721;在这里我把代码直接粘出来吧:
1 Display* dpy = XOpenDisplay(NULL);
2 if( dpy == NULL)
3 {
4 cout << "Display wrong!" << endl;
5 return false;
6 }
7 Window root = DefaultRootWindow(dpy);
8 GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, None};
9 XVisualInfo* vi= glXChooseVisual(dpy,0,att);
10 if( vi == NULL)
11 {
12 cout << "vi wrong" << endl;
13 return false;
14 }
15 XSetWindowAttributes swa;
16 swa.colormap = XCreateColormap(dpy, root, vi->visual, AllocNone);
17 Window win = XCreateWindow(dpy, root, 0, 0, 600, 600, 0, vi->depth, InputOutput, vi->visual, CWColormap, &swa);
18 GLXContext glc = glXCreateContext(dpy, vi, NULL, GL_TRUE);
19 glXMakeCurrent(dpy, win, glc);
这样以后再调用glewInit就可以了。这时我还觉得不过瘾,我想建立一个opengl 3.0的GLXContext。既然显卡支持,为什么不用呢?在查阅了opengl wiki以后,发现第一个例子就是创建GLXContex 3.0:地址如下:http://www.opengl.org/wiki/Tutorial:_OpenGL_3.0_Context_Creation_(GLX)。看到这个就成功了一半,因为这个代码没有使用glut,但是这个例子中的窗口是show出来的。检查了一下把XMapWindow(...)这一行注释掉就可以了。修改后的代码也贴一下吧:
1 int
2 GPute::CreateGLX3()
3 {
4 Display *display = XOpenDisplay(0);
5
6 if ( !display )
7 {
8 printf( "Failed to open X display\n" );
9 return 1;
10 }
11
12 // Get a matching FB config
13 static int visual_attribs[] =
14 {
15 GLX_X_RENDERABLE , True,
16 GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT,
17 GLX_RENDER_TYPE , GLX_RGBA_BIT,
18 GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR,
19 GLX_RED_SIZE , 8,
20 GLX_GREEN_SIZE , 8,
21 GLX_BLUE_SIZE , 8,
22 GLX_ALPHA_SIZE , 8,
23 GLX_DEPTH_SIZE , 24,
24 GLX_STENCIL_SIZE , 8,
25 GLX_DOUBLEBUFFER , True,
26 //GLX_SAMPLE_BUFFERS , 1,
27 //GLX_SAMPLES , 4,
28 None
29 };
30
31 int glx_major, glx_minor;
32
33 // FBConfigs were added in GLX version 1.3.
34 if ( !glXQueryVersion( display, &glx_major, &glx_minor ) ||
35 ( ( glx_major == 1 ) && ( glx_minor < 3 ) ) || ( glx_major < 1 ) )
36 {
37 printf( "Invalid GLX version" );
38 return 1;
39 }
40
41 printf( "Getting matching framebuffer configs\n" );
42 int fbcount;
43 GLXFBConfig *fbc = glXChooseFBConfig( display, DefaultScreen( display ),
44 visual_attribs, &fbcount );
45 if ( !fbc )
46 {
47 printf( "Failed to retrieve a framebuffer config\n" );
48 return 1;
49 }
50 printf( "Found %d matching FB configs.\n", fbcount );
51
52 // Pick the FB config/visual with the most samples per pixel
53 printf( "Getting XVisualInfos\n" );
54 int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999;
55
56 int i;
57 for ( i = 0; i < fbcount; i++ )
58 {
59 XVisualInfo *vi = glXGetVisualFromFBConfig( display, fbc[i] );
60 if ( vi )
61 {
62 int samp_buf, samples;
63 glXGetFBConfigAttrib( display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf );
64 glXGetFBConfigAttrib( display, fbc[i], GLX_SAMPLES , &samples );
65
66 /*printf( " Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d,"
67 " SAMPLES = %d\n",
68 i, vi -> visualid, (unsigned)samp_buf, (unsigned)samples );*/
69
70 if ( ( best_fbc < 0 ) || ( samp_buf && samples > best_num_samp ) )
71 best_fbc = i, best_num_samp = samples;
72 if ( worst_fbc < 0 || !samp_buf || samples < worst_num_samp )
73 worst_fbc = i, worst_num_samp = samples;
74 }
75 XFree( vi );
76 }
77
78 GLXFBConfig bestFbc = fbc[ best_fbc ];
79
80 // Be sure to free the FBConfig list allocated by glXChooseFBConfig()
81 XFree( fbc );
82
83 // Get a visual
84 XVisualInfo *vi = glXGetVisualFromFBConfig( display, bestFbc );
85 //printf( "Chosen visual ID = 0x%x\n", vi->visualid );
86
87 printf( "Creating colormap\n" );
88 XSetWindowAttributes swa;
89 Colormap cmap;
90 swa.colormap = cmap = XCreateColormap( display,
91 RootWindow( display, vi->screen ),
92 vi->visual, AllocNone );
93 swa.background_pixmap = None ;
94 swa.border_pixel = 0;
95 swa.event_mask = StructureNotifyMask;
96
97 printf( "Creating window\n" );
98 Window win = XCreateWindow( display, RootWindow( display, vi->screen ),
99 0, 0, 100, 100, 0, vi->depth, InputOutput,
100 vi->visual,
101 CWBorderPixel|CWColormap|CWEventMask, &swa );
102 if ( !win )
103 {
104 printf( "Failed to create window.\n" );
105 return 1;
106 }
107
108 // Done with the visual info data
109 XFree( vi );
110
111 XStoreName( display, win, "GL 3.0 Window" );
112
113 //printf( "Mapping window\n" );
114 //XMapWindow( display, win );
115
116 // Get the default screen's GLX extension list
117 const char *glxExts = glXQueryExtensionsString( display,
118 DefaultScreen( display ) );
119
120 // NOTE: It is not necessary to create or make current to a context before
121 // calling glXGetProcAddressARB
122 glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
123 glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)
124 glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );
125
126 GLXContext ctx = 0;
127
128 // Install an X error handler so the application won't exit if GL 3.0
129 // context allocation fails.
130 //
131 // Note this error handler is global. All display connections in all threads
132 // of a process use the same error handler, so be sure to guard against other
133 // threads issuing X commands while this code is running.
134 ctxErrorOccurred = false;
135 int (*oldHandler)(Display*, XErrorEvent*) =
136 XSetErrorHandler(&ctxErrorHandler);
137
138 // Check for the GLX_ARB_create_context extension string and the function.
139 // If either is not present, use GLX 1.3 context creation method.
140 if ( !isExtensionSupported( glxExts, "GLX_ARB_create_context" ) ||
141 !glXCreateContextAttribsARB )
142 {
143 printf( "glXCreateContextAttribsARB() not found"
144 " ... using old-style GLX context\n" );
145 ctx = glXCreateNewContext( display, bestFbc, GLX_RGBA_TYPE, 0, True );
146 }
147
148 // If it does, try to get a GL 3.0 context!
149 else
150 {
151 int context_attribs[] =
152 {
153 GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
154 GLX_CONTEXT_MINOR_VERSION_ARB, 0,
155 //GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
156 None
157 };
158
159 printf( "Creating context\n" );
160 ctx = glXCreateContextAttribsARB( display, bestFbc, 0,
161 True, context_attribs );
162
163 // Sync to ensure any errors generated are processed.
164 XSync( display, False );
165 if ( !ctxErrorOccurred && ctx )
166 printf( "Created GL 3.0 context\n" );
167 else
168 {
169 // Couldn't create GL 3.0 context. Fall back to old-style 2.x context.
170 // When a context version below 3.0 is requested, implementations will
171 // return the newest context version compatible with OpenGL versions less
172 // than version 3.0.
173 // GLX_CONTEXT_MAJOR_VERSION_ARB = 1
174 context_attribs[1] = 1;
175 // GLX_CONTEXT_MINOR_VERSION_ARB = 0
176 context_attribs[3] = 0;
177
178 ctxErrorOccurred = false;
179
180 printf( "Failed to create GL 3.0 context"
181 " ... using old-style GLX context\n" );
182 ctx = glXCreateContextAttribsARB( display, bestFbc, 0,
183 True, context_attribs );
184 }
185 }
186
187 // Sync to ensure any errors generated are processed.
188 XSync( display, False );
189
190 // Restore the original error handler
191 XSetErrorHandler( oldHandler );
192
193 if ( ctxErrorOccurred || !ctx )
194 {
195 printf( "Failed to create an OpenGL context\n" );
196 return 1;
197 }
198
199 // Verifying that context is a direct context
200 if ( ! glXIsDirect ( display, ctx ) )
201 {
202 printf( "Indirect GLX rendering context obtained\n" );
203 }
204 else
205 {
206 printf( "Direct GLX rendering context obtained\n" );
207 }
208
209 printf( "Making context current\n" );
210 glXMakeCurrent( display, win, ctx );
211 return 0;
212
213 }
这样只用在glewInit之前调用 CreateGLX3()这个函数在调用glewInit就可以完成glew的初始化了!

浙公网安备 33010602011771号