{"id":56,"date":"2015-05-14T01:47:45","date_gmt":"2015-05-14T01:47:45","guid":{"rendered":"http:\/\/blog.qubekwest.com\/?p=56"},"modified":"2016-04-14T18:34:24","modified_gmt":"2016-04-14T18:34:24","slug":"tricky-tricky","status":"publish","type":"post","link":"https:\/\/blog.qubekwest.com\/?p=56","title":{"rendered":"Tricky Tricky&#8230;"},"content":{"rendered":"<p>So there I was, wrestling with an unending supply of &#8220;what the heck is going on&#8221; while trying to figure out LWJGL and OpenGL. \u00a0Everything looked right, everything compiled, logically the code made sense, but nothing would show up on my screen. \u00a0I double checked everything, I read more parts of my various books, I looked things up in online tutorials. \u00a0I triple checked and quadruple checked. \u00a0Nothing seemed wrong at all except nothing was showing up.<\/p>\n<p>Over the course of over a week I systematically added more calls to System.out.println() (that&#8217;s Java&#8217;s console output command) than there were functional lines. \u00a0If there was something that some part of the code was doing and I didn&#8217;t already know everything about what it was doing, I&#8217;d add more output. \u00a0Still with dozens of lines of output with everything from confirmation that my configuration file was being found and properly loaded, to the exact contents of the shaders that it was using, to the ID that OpenGL assigned my vertex buffer, I just couldn&#8217;t find a problem.<\/p>\n<p>After days of messing around with this, a friend gave it a shot from scratch and his worked. \u00a0This was obviously frustrating for me, but he gave me his code to look over and compare to mine. \u00a0After an hour or two of picking it over nothing seemed out of place except that he was using the &#8220;BufferUtils&#8221; that is built in to LWJGL. \u00a0I switched mine over to use that and what do you know, suddenly I could see things on my screen.<\/p>\n<p>Now I&#8217;m not one to look a gift horse in the mouth here, but after all my attempts and with my goal being to learn how to do all of this for myself, I really had to know what was different. \u00a0I was using something to the effect of:<\/p>\n<pre>FloatBuffer vertexBuffer = ByteBuffer.allocateDirect( 12 )\r\n                             .asFloatBuffer();<\/pre>\n<p>He was doing:<\/p>\n<pre>FloatBuffer vertexBuffer = BufferUtils.createFloatBuffer( 3 );<\/pre>\n<p>My knowledge of the various buffers comes from use of Java&#8217;s NIO package. \u00a0I had no idea there was a fancy utility class within LWJGL. \u00a0If I had bumped into that knowledge, I would have had a pretty good idea about what I was doing wrong. \u00a0The documentation provided for BufferUtils is pretty detailed about what is going on, if only I&#8217;d known to look. \u00a0In my defense, I&#8217;m primarily learning OpenGL and then mentally translating it to LWJGL.<\/p>\n<p>The secret comes down to byte order. \u00a0In computers there are two ways of representing multi-byte values. \u00a0They are referred to as little endian and big endian. \u00a0In English, they mean that the low-order byte is at the end (on the right) or the high-order byte is at the end respectively.<\/p>\n<p>This is an example of how to represent a two byte value containing the number 17,117 in both ways:<\/p>\n<pre><strong>Little Endian:<\/strong> \u00a001000010 11011101<\/pre>\n<pre><strong>Big Endian:<\/strong> \u00a0   11011101\u00a001000010<\/pre>\n<p>The reason this is important is because my computer (Intel architecture) uses little endian and the Java Virtual Machine (JVM) uses big endian. \u00a0In other words, Java sees everything as correct, all the right numbers show up in my console output, and then when I hand it to the video card everything is in the wrong order. \u00a0This means my fancy triangle had its vertexes somewhere very different than I was expecting (and likely not in the view of the camera at all).<\/p>\n<p>As it turns out, the tiny part I was missing from my code was this:<\/p>\n<pre>FloatBuffer vertexBuffer = ByteBuffer.allocateDirect( 12 )\r\n                             <strong>.order( ByteOrder.nativeOrder() )<\/strong>\r\n                             .asFloatBuffer();<\/pre>\n<p>If that were there, Java would know that it should be using the buffer data in the opposite order it was expecting to use for itself (because it would be setting them up for the real computer instead of the JVM). \u00a0This is not to say I won&#8217;t be using the BufferUtils version, because I will, but now I know how what I had was different from what it needed to be and why it had to be that way.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>So there I was, wrestling with an unending supply of &#8220;what the heck is going on&#8221; while trying to figure out LWJGL and OpenGL. \u00a0Everything looked right, everything compiled, logically the code made sense, but nothing would show up on my screen. \u00a0I double checked everything, I read more parts of my various books, I &hellip; <a href=\"https:\/\/blog.qubekwest.com\/?p=56\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Tricky Tricky&#8230;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-56","post","type-post","status-publish","format-standard","hentry","category-dev"],"_links":{"self":[{"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=\/wp\/v2\/posts\/56","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=56"}],"version-history":[{"count":3,"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=\/wp\/v2\/posts\/56\/revisions"}],"predecessor-version":[{"id":59,"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=\/wp\/v2\/posts\/56\/revisions\/59"}],"wp:attachment":[{"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=56"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=56"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=56"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}