Please use ``` tags to mark code blocks, especially long ones. Keeps the indentation, uses pretty-printing, and doesn’t take up so much space. Fixed that for you.
Glanced over your code, and it looks like you’ve some unneeded code in there. I’d simply it down a bit. Also, there’s some surprising things to me such as passing GLX_CONTEXT_MAJOR/MINOR_VERSION_ARB symbols to glXChooseFBConfig() rather than glXCreateContextAttribsARB(). Are you sure this is valid?
Anyway, here’s a stand-alone, working, test program that creates a new-style context via GLX. Specifically, it requests a 4.3 compatibility context – though you can tweak that. Might give you some ideas. Give it a shot:
//------------------------------------------------------------------------------
// glx_simple_new - Shows how to create an X window and a new-style
// GL context without GLUT or any helper libraries.
//
// COMPILE WITH:
// g++ -g -o glx_simple_new glx_simple_new.cxx -lGLU -lGL -lX11
//------------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/time.h>
#define GL_GLEXT_PROTOTYPES
#define GLX_GLXEXT_PROTOTYPES
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glx.h>
struct MyWin
{
Display *display;
Window win;
bool displayed;
int width;
int height;
};
//----------------------------------------------------------------------------
const int WIN_XPOS = 256;
const int WIN_YPOS = 64;
const int WIN_XRES = 320;
const int WIN_YRES = 320;
const int NUM_SAMPLES = 4;
//----------------------------------------------------------------------------
MyWin Win;
//----------------------------------------------------------------------------
double elapsedMsec( const struct timeval &start, const struct timeval &stop )
{
return ( ( stop.tv_sec - start.tv_sec ) * 1000.0 +
( stop.tv_usec - start.tv_usec ) / 1000.0 );
}
//----------------------------------------------------------------------------
double elapsedUsec( const struct timeval &start, const struct timeval &stop )
{
return ( ( stop.tv_sec - start.tv_sec ) * 1000000.0 +
( stop.tv_usec - start.tv_usec ) );
}
//-----------------------------------------------------------------------------
/// check() - Check for GL errors, and report any queued
void check( const char hdr[] = "" )
{
int err;
while ( ( err = glGetError() ) != GL_NO_ERROR )
fprintf( stderr, "OpenGL Error at %s: %s", hdr, gluErrorString(err) );
}
//----------------------------------------------------------------------------
void displayCB()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
//---------------------------------------------------
// FIXME: Insert GL draw code here
//---------------------------------------------------
// Display it
glXSwapBuffers( Win.display, Win.win );
check( "displayCB()" );
}
//----------------------------------------------------------------------------
void keyboardCB( KeySym sym, unsigned char key, int x, int y,
bool &setting_change )
{
switch ( tolower( key ) )
{
case 27:
// ESCape - We're done!
exit (0);
break;
case 'k':
printf( "You hit the 'k' key" );
break;
case 0:
switch ( sym )
{
case XK_Left :
printf( "You hit the Left Arrow key" );
break;
case XK_Right :
printf( "You hit the Right Arrow key" );
break;
}
break;
}
}
//----------------------------------------------------------------------------
void reshapeCB( int width, int height )
{
Win.width = width;
Win.height = height;
}
//----------------------------------------------------------------------------
/** chooseFBConfig() - Try to find a framebuffer config that matches
* the specified pixel requirements.
*/
GLXFBConfig chooseFBConfig( Display *display, int screen )
{
// Default template
static const int Visual_attribs[] =
{
GLX_X_RENDERABLE , True,
GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT,
GLX_RENDER_TYPE , GLX_RGBA_BIT,
GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR,
GLX_RED_SIZE , 8,
GLX_GREEN_SIZE , 8,
GLX_BLUE_SIZE , 8,
GLX_ALPHA_SIZE , 8,
GLX_DEPTH_SIZE , 24,
GLX_STENCIL_SIZE , 8,
GLX_DOUBLEBUFFER , True,
GLX_SAMPLE_BUFFERS , 1,
GLX_SAMPLES , 4,
None
};
int attribs [ 100 ] ;
memcpy( attribs, Visual_attribs, sizeof( Visual_attribs ) );
// DELETED
GLXFBConfig ret = 0;
int fbcount;
GLXFBConfig *fbc = glXChooseFBConfig( display, screen,
attribs, &fbcount );
if ( fbc )
{
if ( fbcount >= 1 )
ret = fbc[0];
XFree( fbc );
}
return ret;
}
//----------------------------------------------------------------------------
GLXContext createContext( Display *display, int screen,
GLXFBConfig fbconfig, XVisualInfo *visinfo,
Window window )
{
#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
// Verify GL driver supports glXCreateContextAttribsARB()
// Create an old-style GLX context first, to get the correct function ptr.
glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
GLXContext ctx_old = glXCreateContext( display, visinfo, 0, True );
if ( !ctx_old )
{
printf( "Could not even allocate an old-style GL context!" );
exit(1);
}
glXMakeCurrent ( display, window, ctx_old ) ;
// Verify that GLX implementation supports the new context create call
if ( strstr( glXQueryExtensionsString( display, screen ),
"GLX_ARB_create_context" ) != 0 )
glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)
glXGetProcAddress( (const GLubyte *) "glXCreateContextAttribsARB" );
if ( !glXCreateContextAttribsARB )
{
printf( "Can't create new-style GL context" );
exit(1);
}
// Got the pointer. Nuke old context.
glXMakeCurrent( display, None, 0 );
glXDestroyContext( display, ctx_old );
// Try to allocate a GL 4.3 COMPATIBILITY context
static int Context_attribs[] =
{
GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
GLX_CONTEXT_MINOR_VERSION_ARB, 3,
GLX_CONTEXT_PROFILE_MASK_ARB , GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
//GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
//GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
//GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_DEBUG_BIT_ARB,
None
};
GLXContext context = glXCreateContextAttribsARB( display, fbconfig, 0,
True, Context_attribs );
// Forcably wait on any resulting X errors
XSync( display, False );
if ( !context )
{
printf( "Failed to allocate a GL 4.3 context" );
exit(1);
}
printf( "Created GL 4.3 context" );
return context;
}
//----------------------------------------------------------------------------
void createWindow()
{
// Init X and GLX
Win.displayed = false;
Display *display = Win.display = XOpenDisplay( ":0.0" );
if ( !display )
printf( "Cannot open X display" );
int screen = DefaultScreen( display );
Window root_win = RootWindow( display, screen );
if ( !glXQueryExtension( display, 0, 0 ) )
printf( "X Server doesn't support GLX extension" );
// Pick an FBconfig and visual
GLXFBConfig fbconfig = chooseFBConfig( display, screen );
if ( !fbconfig )
{
printf( "Failed to get GLXFBConfig" );
exit(1);
}
XVisualInfo *visinfo = glXGetVisualFromFBConfig( display, fbconfig );
if ( !visinfo )
{
printf( "Failed to get XVisualInfo" );
exit(1);
}
printf( "X Visual ID = 0x%.2x", int( visinfo->visualid ) );
// Create the X window
XSetWindowAttributes winAttr ;
winAttr.event_mask = StructureNotifyMask | KeyPressMask ;
winAttr.background_pixmap = None ;
winAttr.background_pixel = 0 ;
winAttr.border_pixel = 0 ;
winAttr.colormap = XCreateColormap( display, root_win,
visinfo->visual, AllocNone );
unsigned int mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask;
Window win = Win.win = XCreateWindow ( display, root_win,
WIN_XPOS, WIN_YPOS,
WIN_XRES, WIN_YRES, 0,
visinfo->depth, InputOutput,
visinfo->visual, mask, &winAttr ) ;
XStoreName( Win.display, win, "My GLX Window");
// Create an OpenGL context and attach it to our X window
GLXContext context = createContext( display, screen, fbconfig, visinfo, win );
if ( ! glXMakeCurrent( display, win, context ) )
printf( "glXMakeCurrent failed." );
if ( ! glXIsDirect ( display, glXGetCurrentContext() ) )
printf( "Indirect GLX rendering context obtained" );
// Display the window
XMapWindow( display, win );
if ( ! glXMakeCurrent( display, win, context ) )
printf( "glXMakeCurrent failed." );
check( "createWindow()" );
printf( "Window Size = %d x %d", WIN_XRES, WIN_YRES );
printf( "Window Samples = %d", NUM_SAMPLES );
}
//----------------------------------------------------------------------------
void processXEvents( Atom wm_protocols, Atom wm_delete_window )
{
bool setting_change = false;
while ( XEventsQueued( Win.display, QueuedAfterFlush ) )
{
XEvent event;
XNextEvent( Win.display, &event );
if( event.xany.window != Win.win )
continue;
switch ( event.type )
{
case MapNotify:
{
Win.displayed = true;
break;
}
case ConfigureNotify:
{
XConfigureEvent &cevent = event.xconfigure;
reshapeCB( cevent.width, cevent.height );
break;
}
case KeyPress:
{
char chr;
KeySym symbol;
XComposeStatus status;
XLookupString( &event.xkey, &chr, 1, &symbol, &status );
keyboardCB( symbol, chr, event.xkey.x, event.xkey.y,
setting_change );
break;
}
case ClientMessage:
{
if ( event.xclient.message_type == wm_protocols &&
Atom( event.xclient.data.l[0] ) == wm_delete_window )
{
//printf( "Received WM_DELETE_WINDOW" );
exit(0);
}
break;
}
}
}
}
//----------------------------------------------------------------------------
void mainLoop()
{
// Register to receive window close events (the "X" window manager button)
Atom wm_protocols = XInternAtom( Win.display, "WM_PROTOCOLS" , False);
Atom wm_delete_window = XInternAtom( Win.display, "WM_DELETE_WINDOW", False);
XSetWMProtocols( Win.display, Win.win, &wm_delete_window, True );
while (1)
{
// Redraw window (after it's mapped)
if ( Win.displayed )
displayCB();
// Update frame rate
static timeval last_xcheck = {0,0};
struct timeval now;
gettimeofday( &now, 0 );
// Check X events every 1/10 second
if ( elapsedMsec( last_xcheck, now ) > 100 )
{
processXEvents( wm_protocols, wm_delete_window );
last_xcheck = now;
}
}
}
//----------------------------------------------------------------------------
int main( int argc, char *argv[] )
{
// Init globals
Win.width = WIN_XRES, Win.height = WIN_YRES;
// Create context and window
createWindow();
// Init OpenGL
glViewport ( 0, 0, Win.width, Win.height );
glColorMask ( 1,1,1,1 );
glClearColor( 0,0,1,1 );
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
// Go
printf( "Valid keys: Left, Right, k, ESC" );
printf( "Press ESC to quit" );
mainLoop();
return 0;
}