{"id":2670,"date":"2016-12-03T15:25:40","date_gmt":"2016-12-03T22:25:40","guid":{"rendered":"http:\/\/mattfife.com\/?p=2670"},"modified":"2016-12-05T14:27:01","modified_gmt":"2016-12-05T21:27:01","slug":"opengl-on-linux-code","status":"publish","type":"post","link":"https:\/\/mattfife.com\/?p=2670","title":{"rendered":"&#8220;Hello World&#8221; OpenGL on Linux"},"content":{"rendered":"<p>Writing the OpenGL context creation plumbing on Linux isn&#8217;t 100% intuitive. It&#8217;s always good to have a handy getting started guide. With developers increasingly using engines such as Unity, the number of people writing directly to OpenGL is shrinking &#8211; and so are some of the online resources to get over this initial step. I decided to collect a few links and copy critical\u00a0sample code here for when I need to whip something up quickly.<\/p>\n<p>&nbsp;<\/p>\n<p>Some links to good &#8216;hello world&#8217; Linux GL samples:<br \/>\n<a href=\"https:\/\/github.com\/jckarter\/hello-gl\" target=\"_blank\">https:\/\/github.com\/jckarter\/hello-gl<\/a><br \/>\n<a href=\"https:\/\/www.opengl.org\/wiki\/Tutorial:_OpenGL_3.0_Context_Creation_(GLX)\" target=\"_blank\">https:\/\/www.opengl.org\/wiki\/Tutorial:_OpenGL_3.0_Context_Creation_(GLX)<br \/>\n<\/a><a href=\"http:\/\/www-f9.ijs.si\/~matevz\/docs\/007-2392-003\/sgi_html\/ch04.html\" target=\"_blank\">http:\/\/www-f9.ijs.si\/~matevz\/docs\/007-2392-003\/sgi_html\/ch04.html<\/a><\/p>\n<p>&nbsp;<\/p>\n<p>Code:<br \/>\nTaken from:\u00a0<a href=\"https:\/\/www.opengl.org\/sdk\/docs\/man2\/xhtml\/glXIntro.xml\" target=\"_blank\">https:\/\/www.opengl.org\/sdk\/docs\/man2\/xhtml\/glXIntro.xml<\/a><\/p>\n<p>Below is a minimal example of creating an RGBA-format X window that&#8217;s compatible with OpenGL using GLX 1.3 commands. The window is cleared to yellow when the program runs. The program does minimal error checking; all return values should be checked.<\/p>\n<pre class=\"programlisting\" xml:space=\"preserve\">#include &lt; stdio.h &gt;\r\n#include &lt; stdlib.h &gt;\r\n#include &lt; GL\/gl.h &gt;\r\n#include &lt; GL\/glx.h &gt;\r\n\r\nint singleBufferAttributess[] = {\r\n    GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,\r\n    GLX_RENDER_TYPE,   GLX_RGBA_BIT,\r\n    GLX_RED_SIZE,      1,   \/* Request a single buffered color buffer *\/\r\n    GLX_GREEN_SIZE,    1,   \/* with the maximum number of color bits  *\/\r\n    GLX_BLUE_SIZE,     1,   \/* for each component                     *\/\r\n    None\r\n};\r\n\r\nint doubleBufferAttributes[] = {\r\n    GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,\r\n    GLX_RENDER_TYPE,   GLX_RGBA_BIT,\r\n    GLX_DOUBLEBUFFER,  True,  \/* Request a double-buffered color buffer with *\/\r\n    GLX_RED_SIZE,      1,     \/* the maximum number of bits per component    *\/\r\n    GLX_GREEN_SIZE,    1, \r\n    GLX_BLUE_SIZE,     1,\r\n    None\r\n};\r\n\r\n\r\nstatic Bool WaitForNotify( Display *dpy, XEvent *event, XPointer arg ) {\r\n    return (event-&gt;type == MapNotify) &amp;&amp; (event-&gt;xmap.window == (Window) arg);\r\n}\r\nint main( int argc, char *argv[] )\r\n{\r\n    Display              *dpy;\r\n    Window                xWin;\r\n    XEvent                event;\r\n    XVisualInfo          *vInfo;\r\n    XSetWindowAttributes  swa;\r\n    GLXFBConfig          *fbConfigs;\r\n    GLXContext            context;\r\n    GLXWindow             glxWin;\r\n    int                   swaMask;\r\n    int                   numReturned;\r\n    int                   swapFlag = True;\r\n\r\n    \/* Open a connection to the X server *\/\r\n    dpy = XOpenDisplay( NULL );\r\n    if ( dpy == NULL ) {\r\n        printf( \"Unable to open a connection to the X servern\" );\r\n        exit( EXIT_FAILURE );\r\n    }\r\n\r\n    \/* Request a suitable framebuffer configuration - try for a double \r\n    ** buffered configuration first *\/\r\n    fbConfigs = glXChooseFBConfig( dpy, DefaultScreen(dpy),\r\n                                   doubleBufferAttributes, &amp;numReturned );\r\n\r\n    if ( fbConfigs == NULL ) {  \/* no double buffered configs available *\/\r\n      fbConfigs = glXChooseFBConfig( dpy, DefaultScreen(dpy),\r\n                                     singleBufferAttributess, &amp;numReturned );\r\n      swapFlag = False;\r\n    }\r\n\r\n    \/* Create an X colormap and window with a visual matching the first\r\n    ** returned framebuffer config *\/\r\n    vInfo = glXGetVisualFromFBConfig( dpy, fbConfigs[0] );\r\n\r\n    swa.border_pixel = 0;\r\n    swa.event_mask = StructureNotifyMask;\r\n    swa.colormap = XCreateColormap( dpy, RootWindow(dpy, vInfo-&gt;screen),\r\n                                    vInfo-&gt;visual, AllocNone );\r\n\r\n    swaMask = CWBorderPixel | CWColormap | CWEventMask;\r\n\r\n    xWin = XCreateWindow( dpy, RootWindow(dpy, vInfo-&gt;screen), 0, 0, 256, 256,\r\n                          0, vInfo-&gt;depth, InputOutput, vInfo-&gt;visual,\r\n                          swaMask, &amp;swa );\r\n\r\n    \/* Create a GLX context for OpenGL rendering *\/\r\n    context = glXCreateNewContext( dpy, fbConfigs[0], GLX_RGBA_TYPE,\r\n\t\t\t\t NULL, True );\r\n\r\n    \/* Create a GLX window to associate the frame buffer configuration\r\n    ** with the created X window *\/\r\n    glxWin = glXCreateWindow( dpy, fbConfigs[0], xWin, NULL );\r\n    \r\n    \/* Map the window to the screen, and wait for it to appear *\/\r\n    XMapWindow( dpy, xWin );\r\n    XIfEvent( dpy, &amp;event, WaitForNotify, (XPointer) xWin );\r\n\r\n    \/* Bind the GLX context to the Window *\/\r\n    glXMakeContextCurrent( dpy, glxWin, glxWin, context );\r\n\r\n    \/* OpenGL rendering ... *\/\r\n    glClearColor( 1.0, 1.0, 0.0, 1.0 );\r\n    glClear( GL_COLOR_BUFFER_BIT );\r\n\r\n    glFlush();\r\n    \r\n    if ( swapFlag )\r\n        glXSwapBuffers( dpy, glxWin );\r\n\r\n    sleep( 10 );\r\n    exit( EXIT_SUCCESS );\r\n}<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Writing the OpenGL context creation plumbing on Linux isn&#8217;t 100% intuitive. It&#8217;s always good to have a handy getting started guide. With developers increasingly using engines such as Unity, the number of people writing directly to OpenGL is shrinking &#8211; and so are some of the online resources to get over this initial step. I decided to collect a few links and copy critical\u00a0sample code here for when I need to whip something up quickly. &nbsp; Some links to good&#8230;<\/p>\n<p class=\"read-more\"><a class=\"btn btn-default\" href=\"https:\/\/mattfife.com\/?p=2670\"> Read More<span class=\"screen-reader-text\">  Read More<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":true,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"OpenGL on Linux code","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[7,5],"tags":[],"class_list":["post-2670","post","type-post","status-publish","format-standard","hentry","category-technicalprogramming","category-technical"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p4WECr-H4","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/mattfife.com\/index.php?rest_route=\/wp\/v2\/posts\/2670","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mattfife.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mattfife.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mattfife.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/mattfife.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2670"}],"version-history":[{"count":10,"href":"https:\/\/mattfife.com\/index.php?rest_route=\/wp\/v2\/posts\/2670\/revisions"}],"predecessor-version":[{"id":2695,"href":"https:\/\/mattfife.com\/index.php?rest_route=\/wp\/v2\/posts\/2670\/revisions\/2695"}],"wp:attachment":[{"href":"https:\/\/mattfife.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2670"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mattfife.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2670"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mattfife.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2670"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}