{"id":12304,"date":"2011-07-13T07:46:49","date_gmt":"2011-07-13T12:46:49","guid":{"rendered":"http:\/\/www.shamusyoung.com\/twentysidedtale\/?p=12304"},"modified":"2011-07-13T07:50:14","modified_gmt":"2011-07-13T12:50:14","slug":"project-frontier-16-interfaced","status":"publish","type":"post","link":"https:\/\/www.shamusyoung.com\/twentysidedtale\/?p=12304","title":{"rendered":"Project Frontier #16: Interface&#8217;d"},"content":{"rendered":"<p>I need something handy that will let me change program options without needing to compile.  Right now I have everything bound to mysterious and unexplained hotkeys. There are enough of these that I&#8217;m getting confused. Hotkeys are great for turning things on and off, but terrible for fine-tuning options. It looks like I need some sort of interface for my program.<\/p>\n<p><table   class=\"\" cellpadding='0' cellspacing='0' border='0' align='center'><tr><td><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/frontier16_interface.jpg' class='insetimage'   alt='This computer interface is notable for the upper-arm and back conditioning required to use it. The upside is that, if it&#8217;s adopted, Photoshop artists will eventually look like bodybuilders.' title='This computer interface is notable for the upper-arm and back conditioning required to use it. The upside is that, if it&#8217;s adopted, Photoshop artists will eventually look like bodybuilders.'\/><\/td><\/tr><tr><td class='insetcaption'>This computer interface is notable for the upper-arm and back conditioning required to use it. The upside is that, if it&#8217;s adopted, Photoshop artists will eventually look like bodybuilders.<\/td><\/tr><\/table><\/p>\n<p>Now, I&#8217;m always banging on about how libraries should be as focused and unencumbered as possible, how you shouldn&#8217;t need to go on a multi-stage fetch quest to get the thing to compile like you were trying to assemble the pieces of the Tri-Force or something.  The problem is, there is pretty much no way around this.  Interfaces need to use fonts, and fonts are fiendishly complex beasts. Interfaces need to render stuff, and rendering is complicated.  They need to process keyboard and mouse input, and those are complicated. (It seems simple, but tracking keyboards and mouse wheels and all the different things that can happen with the CTRL, ALT, and NUMPAD&#8230; it gets very hairy.) That&#8217;s a lot of things for one library to do, on top of running a window system with buttons and scrollbars and the ability to tab between interface elements and all of the other tiny details that we all take for granted.<\/p>\n<p>Still, the inability to adjust options is really killing my productivity. So let&#8217;s see what we can find.<\/p>\n<p><!--more-->Let&#8217;s see. We need an interface system that works with OpenGL.  We&#8217;ve got <a href=\"http:\/\/www.cegui.org.uk\/\">Crazy Eddie&#8217;s GUI system<\/a>, <a href=\"http:\/\/www.fltk.org\/\">FLTK<\/a>, <a href=\"http:\/\/glam.sourceforge.net\/\">GLAM<\/a>, <a href=\"http:\/\/glui.sourceforge.net\/\">GLUI<\/a>, <a href=\"http:\/\/glgooey.sourceforge.net\/\">GL Gooey<\/a>, <a href=\"http:\/\/libufo.sourceforge.net\/\">LibUFO<\/a>, <a href=\"http:\/\/qt.nokia.com\/products\/\">Qt<\/a>, <a href=\"http:\/\/turska.sourceforge.net\/\">Turska<\/a>, <a href=\"http:\/\/www.wxwidgets.org\/\">wxWidgets<\/a>&#8230; and probably others.<\/p>\n<p>Wow.  That is a very daunting list.  Some of these libraries won&#8217;t have the functionality I need. Some will, but will have horrible dependency issues (some may even encapsulate others, or be forks of other items in the list, I don&#8217;t know yet) that will make them prohibitively difficult to use.  Others will have horrible C++ interfaces that make a cluttered mess of your code.  Some will have the functionality I need, but will lack the visual customization I need. (I know a few of these are designed to create standard &#8220;windows&#8221; style interfaces, which would look just awful floating atop my Seussian fantasy world.) Some might have all of the above, but be tied to a particular platform.  Or lack proper documentation.  Or turn out to be long-abandoned projects that no longer work due to shifting technology.<\/p>\n<p>I could easily burn a couple of days downloading each and every library, getting it to (hopefully) compile, testing it out, evaluating the interface, the looks, reviewing the documentation, and making sure it actually has all the features it claims to have.  (I don&#8217;t want to install the thing into my project and three days later discover that something fundamental like &#8220;text input boxes&#8221; is still on the to-do list.)  This promises to be a massive investment of time.  The truth is, I&#8217;m not ready to make this kind of commitment. Really.  It&#8217;s not you, it&#8217;s me. I just can&#8217;t afford to be tied down at this point in the development cycle.  <\/p>\n<p>I began this project as a tech demo, that <em>could<\/em> become a game.  But the tech demo comes first. And adding a all-singing, all-dancing, multi-window interface falls way, way outside of that scope.  <\/p>\n<p>Thinking about this more, what I really need is a &#8220;Quake-style&#8221; console. If you ever hit the tilde key in Quake, you probably saw the text window that opens up.  That window lets you enter commands, change variables, and generally control the application without needing menus and scroll boxes and the like.  This is exactly the reason console windows exist: For the proof-of-concept \/ prototyping stage of a project. <\/p>\n<p>I ask Google, and it brings me this: <a href=\"http:\/\/www.robots.ox.ac.uk\/~gsibley\/GLConsole\/\">glConsole<\/a>.  <\/p>\n<p>The bad news is that it was developed on another platform (Linux, I suspect) and there are no binaries available.  So I&#8217;m going to have to get it to compile.  It uses CMAKE, which is supposedly a totally cross-platform system for compiling code, a claim of which I am mildly skeptical.  Well, it can&#8217;t hurt.  Let&#8217;s see how this goes&#8230;<\/p>\n<p>(Two hours later.)<\/p>\n<p>I return to you a changed man.  Everything I knew was wrong. CMAKE took a little self-education to use, but once I had the knowledge it did its job flawlessly.   There was an odd compile problem where glConsole complained that it didn&#8217;t match it own version number or some such piffle, but commenting out a couple of lines fixed that right up.  <\/p>\n<p>Let me tell you about glConsole&#8230;<\/p>\n<p><table   class=\"\" cellpadding='0' cellspacing='0' border='0' align='center'><tr><td><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/frontier16_1.jpg' class='insetimage'   alt='frontier16_1.jpg' title='frontier16_1.jpg'\/><\/td><\/tr><\/table><\/p>\n<p>It works. It works beautifully. It works seamlessly. It dropped directly into my project with no additional dependencies. It displays text, but I have no idea how.  I don&#8217;t see a bitmap among its resources and it doesn&#8217;t do any font loading.  It just magically makes text.  I suppose I could look at the source, but so far there&#8217;s been no reason to do so.  I was able to add it to my project in, I kid you not, five lines of code.  I tell it when to open and close.  I tell it when to draw. I feed it keypresses.  That&#8217;s it. Done. I don&#8217;t even need to initialize it. <\/p>\n<p><table   class=\"\" cellpadding='0' cellspacing='0' border='0' align='center'><tr><td><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/frontier16_2.jpg' class='insetimage'   alt='frontier16_2.jpg' title='frontier16_2.jpg'\/><\/td><\/tr><\/table><\/p>\n<p>Even better, it comes with a bunch of other features:<\/p>\n<ol>\n<li>Built-in environment variables.  I create them and access them at will. It keeps track of them for me, saves them, remembers them between sessions.  It even has auto-complete, so it can remind me of my own variable names while I&#8217;m typing them in the console.\n<\/li>\n<li>Environment variables can be organized into groups.  I have one group: render.wireframe, render.lighting, and render.textured.  And another group: mouse.invert, and mouse.sensitivity. This system can plug into another, so when I DO add a full-featured interface, I&#8217;ll already have all of the functionality implemented.  I&#8217;ll just need to have the interface change the already-existing environment variables and it will be done.\n<\/li>\n<li>It can save options into any file I like.  It can save groups or sub-groups of options.  So, I can stick all of the player data into a group:  player.position, player.heading, player.camera_zoom, etc.  Then I can save all of the player.* options into a file.  Boom. My save-game system is done, and I wasn&#8217;t even planning on working on that this week. <em>I got it done as a side-effect of adding this library.<\/em>\n<\/li>\n<li>It keeps a command history, which persists between sessions.  So, I open up the console window and hit the up arrow to cycle through previously typed commands, <em>even if I closed the program since I typed them<\/em>.  This is incredibly useful when I&#8217;m debugging and iterating very quickly, needing to try the same options over and over.\n<\/li>\n<li>I can execute functions from within the console.  So, I can have commands to save the game, load the game, restart the rendering subsystem, purge texture data, or whatever else is needed for testing.\n<\/li>\n<\/ol>\n<p><table   class=\"\" cellpadding='0' cellspacing='0' border='0' align='center'><tr><td><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/frontier16_3.jpg' class='insetimage'   alt='frontier16_3.jpg' title='frontier16_3.jpg'\/><\/td><\/tr><\/table><\/p>\n<p>I&#8217;m dumbfounded.  Not only did this library perfectly and seamlessly solve the problem I had in mind, but it solved future problems I hadn&#8217;t yet considered.  Author <a href=\"http:\/\/www.robots.ox.ac.uk\/~gsibley\/Personal\/\">Gabe Sibley<\/a> has shamed me as a coder.  I&#8217;ve used hackjob libraries downloaded from the internet.  I&#8217;ve used enterprise level solutions that cost tens of thousands of dollars to license.  And nothing I&#8217;ve ever used as been as smooth to integrate and intuitively designed as glConsole. <\/p>\n<p>&#8220;If I could write software like that, I&#8217;d call myself a programmer.&#8221;<\/p>\n<p>Onward!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I need something handy that will let me change program options without needing to compile. Right now I have everything bound to mysterious and unexplained hotkeys. There are enough of these that I&#8217;m getting confused. Hotkeys are great for turning things on and off, but terrible for fine-tuning options. It looks like I need some [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[66],"tags":[],"class_list":["post-12304","post","type-post","status-publish","format-standard","hentry","category-programming"],"_links":{"self":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/posts\/12304","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=12304"}],"version-history":[{"count":0,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/posts\/12304\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=12304"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=12304"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=12304"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}