PDA

View Full Version : A simple doubt - GLX OpenGl 3.0+ Core profile App



devardeb
06-29-2012, 08:09 PM
Hello, I am trying to do an Application using OpenGL3.3 with a core profile, though, it isn't rendering anything. Supposedly a white triangle should appear on the screen.
The code is copied soon below and it is also available on 797:



// extracted from http://www.opengl.org/wiki/Tutorial:_OpenGL_3.0_Context_Creation_%28GLX%29

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include "Vector3f.h"


#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
#define ESCAPE 27

GLuint VBO;

// prototypes
void render();
static void CreateVertexBuffer();

// Helper to check for extension string presence. Adapted from:
// http://www.opengl.org/resources/features/OGLextensions/
static bool isExtensionSupported(const char *extList, const char *extension)

{

const char *start;
const char *where, *terminator;

/* Extension names should not have spaces. */
where = strchr(extension, ' ');
if ( where || *extension == '\0' )
return false;

/* It takes a bit of care to be fool-proof about parsing the
OpenGL extensions string. Don't be fooled by sub-strings,
etc. */
for ( start = extList; ; ) {
where = strstr( start, extension );

if ( !where )
break;

terminator = where + strlen( extension );

if ( where == start || *(where - 1) == ' ' )
if ( *terminator == ' ' || *terminator == '\0' )
return true;

start = terminator;
}

return false;
}

static bool ctxErrorOccurred = false;
static int ctxErrorHandler( Display *dpy, XErrorEvent *ev )
{
ctxErrorOccurred = true;
return 0;
}

Display *display;
Window win;

int main (int argc, char ** argv)
{
display = XOpenDisplay(0);
XEvent event;

if ( !display )
{
printf( "Failed to open X display\n" );
exit(1);
}

// Get a matching FB config
static 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 glx_major, glx_minor;

// FBConfigs were added in GLX version 1.3.
if ( !glXQueryVersion( display, &glx_major, &glx_minor ) ||
( ( glx_major == 1 ) && ( glx_minor < 3 ) ) || ( glx_major < 1 ) )
{
printf( "Invalid GLX version" );
exit(1);
}

printf( "Getting matching framebuffer configs\n" );
int fbcount;
GLXFBConfig *fbc = glXChooseFBConfig( display, DefaultScreen( display ),
visual_attribs, &fbcount );
if ( !fbc )
{
printf( "Failed to retrieve a framebuffer config\n" );
exit(1);
}
printf( "Found %d matching FB configs.\n", fbcount );

// Pick the FB config/visual with the most samples per pixel
printf( "Getting XVisualInfos\n" );
int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999;

int i;
for ( i = 0; i < fbcount; i++ )
{
XVisualInfo *vi = glXGetVisualFromFBConfig( display, fbc[i] );
if ( vi )
{
int samp_buf, samples;
glXGetFBConfigAttrib( display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf );
glXGetFBConfigAttrib( display, fbc[i], GLX_SAMPLES , &samples );

printf( " Matching fbconfig %d, visual ID 0x%2li: SAMPLE_BUFFERS = %d,"
" SAMPLES = %d\n",
i, vi->visualid, samp_buf, samples );

if ( (best_fbc < 0 || samp_buf) && (samples > best_num_samp) )
best_fbc = i, best_num_samp = samples;
if ( worst_fbc < 0 || !samp_buf || samples < worst_num_samp )
worst_fbc = i, worst_num_samp = samples;
}
XFree( vi );
}

GLXFBConfig bestFbc = fbc[ best_fbc ];

// Be sure to free the FBConfig list allocated by glXChooseFBConfig()
XFree( fbc );

// Get a visual
XVisualInfo *vi = glXGetVisualFromFBConfig( display, bestFbc );
printf( "Chosen visual ID = 0x%li\n", vi->visualid );

printf( "Creating colormap\n" );
XSetWindowAttributes swa;
Colormap cmap;
swa.colormap = cmap = XCreateColormap( display,
RootWindow( display, vi->screen ),
vi->visual, AllocNone );
swa.background_pixmap = None ;
swa.border_pixel = 0;
swa.event_mask = StructureNotifyMask;

printf( "Creating window\n" );
win = XCreateWindow( display, RootWindow( display, vi->screen ),
0, 0, 100, 100, 0, vi->depth, InputOutput,
vi->visual,
CWBorderPixel|CWColormap|CWEventMask, &swa );
if ( !win )
{
printf( "Failed to create window.\n" );
exit(1);
}

// Done with the visual info data
XFree( vi );

XStoreName( display, win, "GL 3.0 Window" );

printf( "Mapping window\n" );
XMapWindow( display, win );

// Get the default screen's GLX extension list
const char *glxExts = glXQueryExtensionsString( display,
DefaultScreen( display ) );

// NOTE: It is not necessary to create or make current to a context before
// calling glXGetProcAddressARB
glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)
glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );

GLXContext ctx = 0;

// Install an X error handler so the application won't exit if GL 3.0
// context allocation fails.
//
// Note this error handler is global. All display connections in all threads
// of a process use the same error handler, so be sure to guard against other
// threads issuing X commands while this code is running.
ctxErrorOccurred = false;
int (*oldHandler)(Display*, XErrorEvent*) =
XSetErrorHandler(&ctxErrorHandler);

// Check for the GLX_ARB_create_context extension string and the function.
// If either is not present, use GLX 1.3 context creation method.
if ( !isExtensionSupported( glxExts, "GLX_ARB_create_context" ) ||
!glXCreateContextAttribsARB )
{
printf( "glXCreateContextAttribsARB() not found"
" ... using old-style GLX context\n" );
ctx = glXCreateNewContext( display, bestFbc, GLX_RGBA_TYPE, 0, True );
}

// If it does, try to get a GL 3.0 context!
else
{
int context_attribs[] =
{
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
GLX_CONTEXT_MINOR_VERSION_ARB, 3,
//GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,

None
};



printf( "Creating context\n" );
ctx = glXCreateContextAttribsARB( display, bestFbc, 0,
True, context_attribs );

// Sync to ensure any errors generated are processed.
XSync( display, False );
if ( !ctxErrorOccurred && ctx )
printf( "Created GL 3.0 context\n" );
else
{
// Couldn't create GL 3.0 context. Fall back to old-style 2.x context.
// When a context version below 3.0 is requested, implementations will
// return the newest context version compatible with OpenGL versions less
// than version 3.0.
// GLX_CONTEXT_MAJOR_VERSION_ARB = 1
context_attribs[1] = 1;
// GLX_CONTEXT_MINOR_VERSION_ARB = 0
context_attribs[3] = 0;

ctxErrorOccurred = false;

printf( "Failed to create GL 3.0 context"
" ... using old-style GLX context\n" );
ctx = glXCreateContextAttribsARB( display, bestFbc, 0,
True, context_attribs );
}
}

// Sync to ensure any errors generated are processed.
XSync( display, False );

// Restore the original error handler
XSetErrorHandler( oldHandler );

if ( ctxErrorOccurred || !ctx )
{
printf( "Failed to create an OpenGL context\n" );
exit(1);
}

// Verifying that context is a direct context
if ( ! glXIsDirect ( display, ctx ) )
{
printf( "Indirect GLX rendering context obtained\n" );
}
else
{
printf( "Direct GLX rendering context obtained\n" );
}

printf( "Making context current\n" );
glXMakeCurrent( display, win, ctx );

XSelectInput( display, win, ExposureMask | KeyPressMask );

char msg[] = "Hello World";
KeySym key;

int s = DefaultScreen(display);
printf( "Default Screen: %d\n", s);

char text[10];
//char text;

GC defaultGC = DefaultGC(display, s);

/////////////////////////////////////////
/////////////////////////////////////////
// Must be done after glut is initialized!
GLenum res = glewInit();
if (res != GLEW_OK) {
fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res));
return 1;
}
/////////////////////////////////////////
/////////////////////////////////////////

CreateVertexBuffer();

while( 1 ){
XNextEvent( display, &event );

render();

if( event.type == Expose ){
//XFillRectangle(display, win, defaultGC, 20, 20, 10, 10);
//XDrawString(display, win, defaultGC, 10, 50, msg, strlen(msg));
}
if( event.type == KeyPress ){
//int i = XLookupString( &event.xkey, &text, 1, &key, 0 );

int i = XLookupString( &event.xkey, text, 1, &key, 0 );
if( i == 1 && text[0] == ESCAPE ){
//if( i == 1 && text == ESCAPE ){
break;
}
}
//printf( "Event: %d\n", event.type);

XFillRectangle(display, win, defaultGC, 20, 20, 10, 10);
XDrawString(display, win, defaultGC, 10, 50, msg, strlen(msg));
}

glXMakeCurrent( display, 0, 0 );
glXDestroyContext( display, ctx );

XDestroyWindow( display, win );
XFreeColormap( display, cmap );
XCloseDisplay( display );

return 0;
}

void render(){
glClearColor ( 0, 0.5, 1, 1 );
glClear(GL_COLOR_BUFFER_BIT);

glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

glDrawArrays(GL_TRIANGLES, 0, 3);

glDisableVertexAttribArray(0);


glXSwapBuffers ( display, win );
}

void CreateVertexBuffer(){
Vector3f Vertices[3];
Vertices[0] = Vector3f( -1.0f, -1.0f, 0.0f );
Vertices[1] = Vector3f( 1.0f, -1.0f, 0.0f );
Vertices[2] = Vector3f( 0.0f, 1.0f, 0.0f );

glGenBuffers( 1, &VBO );
glBindBuffer( GL_ARRAY_BUFFER, VBO );
glBufferData( GL_ARRAY_BUFFER, sizeof( Vertices ), Vertices, GL_STATIC_DRAW );
}



If someone could say me why this is happening I would be very grateful

mbentrup
06-30-2012, 02:53 AM
You always have to create and bind a VAO in the core profile.

devardeb
07-01-2012, 05:39 PM
Very Thanks mbentrup. It was my distraction. I read this on a PDF but on my head I was thinking on VBOs.