{"id":2496,"date":"2011-10-08T02:00:59","date_gmt":"2011-10-08T00:00:59","guid":{"rendered":"https:\/\/iguanademos.com\/Jare\/wp\/?p=2496"},"modified":"2012-01-03T06:15:01","modified_gmt":"2012-01-03T04:15:01","slug":"stage3d-vertex-buffer-formats","status":"publish","type":"post","link":"https:\/\/iguanademos.com\/Jare\/wp\/?p=2496","title":{"rendered":"Stage3D Vertex Buffer formats"},"content":{"rendered":"<p>If you played with the Stage3D spinning cube sample I linked in the <a href=\"https:\/\/iguanademos.com\/Jare\/wp\/?p=2480\">previous post<\/a>, you will notice one thing: the vertex colors in the vertex buffer are given as 3 floats (red, green and blue). This is rather wasteful in most cases because color components often vary between 0.0 and 1.0, and it&#8217;s more efficient to specify vertex colors (including alpha) as a single 32-bit value. For example, in hexadecimal notation, 0xFF800040 would mean alpha of 1.0 (0xFF), blue 0.5 (0x80), green 0 (0x00) and red 0.25 (0x40).<\/p>\n<p>If you look in the Stage3D docs, you will find the constant <strong>Context3DVertexBufferFormat.BYTES_4<\/strong> to use in the call to <strong>Context3D.setVertexBufferAt()<\/strong>. But if you naively just change the vertex buffer array to turn each vertex color&#8217;s set of 3 components into a single hex value, make <strong>dataPerVertex<\/strong> = 4 instead of 6, and use <strong>BYTES_4<\/strong> for va1, then you will find that the colors are coming out wrong. Why? Because the function <strong>VertexBuffer3D.uploadFromVector()<\/strong> always stores the values from the Vector in <em>floating point format<\/em>. Of course! This is the most common situation for the components of the vertex positions, normals, texture coordinates and such. But we need our <strong>BYTES_4<\/strong> color value to be stored verbatim as a 32-bit uint.<\/p>\n<p><strong>Vector.&lt;Number&gt;<\/strong>\u00a0and\u00a0<strong>uploadFromVector()<\/strong>\u00a0do not give you control over the byte format of value.\u00a0How do you solve this?<\/p>\n<p><!--more--><\/p>\n<p>You must use a <strong>ByteArray<\/strong>, to which you will copy the values manually with the right format. In our example above, 3 <strong>writeFloat()<\/strong> calls plus a <strong>writeUnsignedInt()<\/strong> for the 32-bit color. A detail that stumped me for a while is that you must ensure the <strong>ByteArray<\/strong> is <strong>Endian.LITTLE_ENDIAN<\/strong>, it defaults to <strong>BIG_ENDIAN<\/strong>. I wrote this function to perform this process, with the aid of an array that stores the format of each varying parameter:<\/p>\n<pre>private static function DumpVectorComponentsIntoByteArray(dest:ByteArray,\r\n                                                          src:Vector.&lt;Number&gt;,\r\n                                                          componentFormats:Array): void\r\n{\r\n\tdest.endian = Endian.LITTLE_ENDIAN;\r\n\tfor (var i:int = 0; i &lt; src.length; )\r\n\t{\r\n\t\tfor (var j:int = 0; j &lt; componentFormats.length; ++j)\r\n\t\t{\r\n\t\t\tswitch (componentFormats[j])\r\n\t\t\t{\r\n\t\t\t\tcase Context3DVertexBufferFormat.FLOAT_2:\r\n\t\t\t\t\tdest.writeFloat(src[i]);\r\n\t\t\t\t\tdest.writeFloat(src[i+1]);\r\n\t\t\t\t\ti += 2;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase Context3DVertexBufferFormat.FLOAT_3:\r\n\t\t\t\t\tdest.writeFloat(src[i]);\r\n\t\t\t\t\tdest.writeFloat(src[i + 1]);\r\n\t\t\t\t\tdest.writeFloat(src[i + 2]);\r\n\t\t\t\t\ti += 3;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase Context3DVertexBufferFormat.FLOAT_4:\r\n\t\t\t\t\tdest.writeFloat(src[i]);\r\n\t\t\t\t\tdest.writeFloat(src[i + 1]);\r\n\t\t\t\t\tdest.writeFloat(src[i + 2]);\r\n\t\t\t\t\tdest.writeFloat(src[i + 3]);\r\n\t\t\t\t\ti += 4;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase Context3DVertexBufferFormat.BYTES_4:\r\n\t\t\t\t\tdest.writeUnsignedInt(src[i]);\r\n\t\t\t\t\t++i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}<\/pre>\n<p>So, in the case of the spinning cube, the component array would be:<\/p>\n<pre>var vertexBufferComponents:Array = new Array(\r\n\tContext3DVertexBufferFormat.FLOAT_3,\r\n\tContext3DVertexBufferFormat.BYTES_4\r\n);<\/pre>\n<p>With that array in hand, another useful function to set the array components into the context:<\/p>\n<pre>private function SetVertexArrays(componentFormats:Array, vertices:VertexBuffer3D): void\r\n{\r\n\tvar offset:int = 0;\r\n\tfor (var j:int = 0; j &lt; componentFormats.length; ++j)\r\n\t{\r\n\t\trenderContext.setVertexBufferAt( j, vertices, offset, componentFormats[j] );\r\n\t\tswitch (componentFormats[j])\r\n\t\t{\r\n\t\t\tcase Context3DVertexBufferFormat.FLOAT_2:\r\n\t\t\t\toffset += 2;\r\n\t\t\t\tbreak;\r\n\t\t\tcase Context3DVertexBufferFormat.FLOAT_3:\r\n\t\t\t\toffset += 3;\r\n\t\t\t\tbreak;\r\n\t\t\tcase Context3DVertexBufferFormat.FLOAT_4:\r\n\t\t\t\toffset += 4;\r\n\t\t\t\tbreak;\r\n\t\t\tcase Context3DVertexBufferFormat.BYTES_4:\r\n\t\t\t\toffset += 1;\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>If you played with the Stage3D spinning cube sample I linked in the previous post, you will notice one thing: the vertex colors in the vertex buffer are given as 3 floats (red, green and blue). This is rather wasteful &hellip; <a href=\"https:\/\/iguanademos.com\/Jare\/wp\/?p=2496\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9,1],"tags":[14,15],"class_list":["post-2496","post","type-post","status-publish","format-standard","hentry","category-development","category-uncategorized","tag-flash","tag-stage3d"],"_links":{"self":[{"href":"https:\/\/iguanademos.com\/Jare\/wp\/index.php?rest_route=\/wp\/v2\/posts\/2496","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/iguanademos.com\/Jare\/wp\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/iguanademos.com\/Jare\/wp\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/iguanademos.com\/Jare\/wp\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/iguanademos.com\/Jare\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2496"}],"version-history":[{"count":10,"href":"https:\/\/iguanademos.com\/Jare\/wp\/index.php?rest_route=\/wp\/v2\/posts\/2496\/revisions"}],"predecessor-version":[{"id":2559,"href":"https:\/\/iguanademos.com\/Jare\/wp\/index.php?rest_route=\/wp\/v2\/posts\/2496\/revisions\/2559"}],"wp:attachment":[{"href":"https:\/\/iguanademos.com\/Jare\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2496"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/iguanademos.com\/Jare\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2496"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/iguanademos.com\/Jare\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2496"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}