<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>gatt.is</title>
	<atom:link href="http://gatt.is/feed/" rel="self" type="application/rss+xml" />
	<link>http://gatt.is</link>
	<description>Matt Gattis&#039; Web Site</description>
	<lastBuildDate>Thu, 02 Feb 2012 00:21:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='gatt.is' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/95346d108a748d46b438edbb8600cca9?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>gatt.is</title>
		<link>http://gatt.is</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://gatt.is/osd.xml" title="gatt.is" />
	<atom:link rel='hub' href='http://gatt.is/?pushpress=hub'/>
		<item>
		<title>Porting OpenGL Rendering to OpenGL ES 2.0</title>
		<link>http://gatt.is/2011/10/10/porting-opengl-rendering-to-opengl-es-2-0/</link>
		<comments>http://gatt.is/2011/10/10/porting-opengl-rendering-to-opengl-es-2-0/#comments</comments>
		<pubDate>Mon, 10 Oct 2011 18:05:28 +0000</pubDate>
		<dc:creator>gattis</dc:creator>
				<category><![CDATA[GPU Programming]]></category>

		<guid isPermaLink="false">http://gatt.is/?p=134</guid>
		<description><![CDATA[Recently I wrote milkshake, which is a port of MilkDrop and projectM to the cloud Internet that allows you to watch music visualizations in your browser while you listen to all the new browser-based streaming music sites like SoundCloud and Rdio. The original renderer, MilkDrop, was written using DirectX APIs for Windows. projectM was a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gatt.is&amp;blog=27168532&amp;post=134&amp;subd=gattis&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Recently I wrote <a href="http://github.com/gattis/milkshake">milkshake</a>, which is a port of <a href="http://www.geisswerks.com/about_milkdrop.html">MilkDrop</a> and <a href="http://projectm.sourceforge.net/">projectM</a> to the <del>cloud</del> Internet that allows you to watch music visualizations in your browser while you listen to all the new browser-based streaming music sites like SoundCloud and Rdio.</p>
<p>The original renderer, MilkDrop, was written using DirectX APIs for Windows. projectM was a reimplementation using OpenGL 1.0 so that the renderer could be used on all platforms, including Mac OS and Linux. I thought it was going to be straightforward to port this OpenGL code to WebGL, but unfortunately for me, WebGL implements a subset of OpenGL 2.0 called OpenGL ES 2.0.</p>
<p>It seems many new platforms are moving to OpenGL ES 2.0 instead of plain OpenGL 2.0, which has a lot of legacy support and is backwards compatible with OpenGL 1.0.  This list includes iOS, Android, and perhaps the next big Linux display sever/compositor, Wayland.  There are many reasons for this but I suppose the biggest is that devices like phones and tablets that don&#8217;t have a general purpose GPU have a Graphics Processor with more constrained resources, and it&#8217;s more cost effective for them to implement a single simpler graphics API.  And despite being a subset, OpenGL ES 2.0 is every bit as powerful as OpenGL 2.0.  I couldn&#8217;t find any resources on converting between the two, so here&#8217;s some basics that will save you a lot of frustration.</p>
<p>The biggest difference between the implementations is that OpenGL ES 2.0 replaces the fixed-function pipeline with programmable shaders.  With the fixed-function pipeline, we were basically given a simple shader program that allowed us to pass in vectors for vertices, colors, and textures, and basic operations to transform the matrices which project the 3D model to our eyes.  With programmable shaders, we can make any shader we want.  So the first step in porting is to emulate the old fixed-function pipeline with a shader of our own:</p>
<p>The Vertex Shader in GLSL:</p>
<pre>    attribute vec4 a_position;
    attribute vec4 a_texCoord;
    varying vec4 v_texCoord;
    attribute vec4 a_color;
    uniform vec4 u_color;
    varying vec4 v_color;
    uniform bool enable_v_color;
    uniform float u_pointsize;
    uniform mat4 mvp_matrix;
    uniform mat4 tx_matrix;
    void main() {
        gl_Position = mvp_matrix * a_position;
        v_texCoord = tx_matrix * a_texCoord;
        if (enable_v_color)
            v_color = a_color;
        else
            v_color = u_color;
        gl_PointSize = u_pointsize;
    }</pre>
<p>The Fragment Shader in GLSL:</p>
<pre>    varying vec4 v_texCoord;
    uniform sampler2D s_texture;
    varying vec4 v_color;
    uniform bool enable_s_texture;
    void main() {
        if (enable_s_texture)
            gl_FragColor = v_color * texture2D(s_texture, v_texCoord.st);
        else
            gl_FragColor = v_color;
    }</pre>
<p>So you can see we&#8217;ve emulated the basic aspects of the fixed-function pipeline in OpenGL Shader Language.  If you have more complex pieces to port, like fog or dynamic lighting, you will also have to convert those.</p>
<p>OpenGL ES 2.0 also doesn&#8217;t do our matrix homework for us, so we have to write all the linear algebra to get the modelview, projection, and texture matrices in a form we can pass to our programmed shader.  I won&#8217;t go into details on how to do this, but you can find most of the OpenGL 1.0 functions like glPushMatrix, glPopMatrix, glMultMatrix, glTranslatef, glRotatef, glOrthof, etc implemented in <a href="http://github.com/gattis/milkshake/blob/master/milkshake.js">milkshake.js</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gattis.wordpress.com/134/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gattis.wordpress.com/134/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gattis.wordpress.com/134/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gattis.wordpress.com/134/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gattis.wordpress.com/134/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gattis.wordpress.com/134/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gattis.wordpress.com/134/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gattis.wordpress.com/134/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gattis.wordpress.com/134/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gattis.wordpress.com/134/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gattis.wordpress.com/134/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gattis.wordpress.com/134/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gattis.wordpress.com/134/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gattis.wordpress.com/134/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gatt.is&amp;blog=27168532&amp;post=134&amp;subd=gattis&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gatt.is/2011/10/10/porting-opengl-rendering-to-opengl-es-2-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/58d69efe12d79da9a59030c04ff3cd37?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gattis</media:title>
		</media:content>
	</item>
	</channel>
</rss>
