{"id":459,"date":"2010-09-19T08:52:25","date_gmt":"2010-09-19T08:52:25","guid":{"rendered":"http:\/\/metaviewsoft.de\/wordpress\/?p=459"},"modified":"2010-09-19T08:58:39","modified_gmt":"2010-09-19T08:58:39","slug":"webos-howto-make-your-2d-sdl-app-palm-pixi-compatible","status":"publish","type":"post","link":"https:\/\/metaviewsoft.de\/wordpress\/?p=459","title":{"rendered":"#WebOS-HowTo: Make your 2D SDL app @Palm Pixi compatible"},"content":{"rendered":"<p>WebOS in the current version of 1.4.5 has a bug regarding 2D-SDL rendering.<\/p>\n<p>Normally, you would create a SDL_Surface, render your object on it and update the screen with help of SDL_Flip() or SDL_UpdateRect() call. This doesn&#8217;t really work on a Pixi: The app works for some seconds and then the screen stops updating.<\/p>\n<p>The only screen update path which works reliable on a Pixi is OpenGL. And therefore this is the way you need to go to bypass this bug.<\/p>\n<p>Using your SDL-Surface as a texture map on a full screen box in OpenGL sounds not very complicated but there are several pitfalls on the way the screen. In the following example I&#8217;ll use OpenGLES1.1.<\/p>\n<p><!--more--><\/p>\n<p>1. We need the correct includes and libraries:<\/p>\n<pre><code>\n\t#include &lt;GLES\/gl.h&gt;\n\t#include &lt;GLES\/glext.h&gt;\n<\/code><\/pre>\n<pre><code>\n\t-lGLES_CM\n<\/code><\/pre>\n<p>2. We need to setup SDL, PDL and OpenGL.<\/p>\n<pre><code>\n\t\/\/ Initialize the SDL library with the Video subsystem\n\tSDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE);\n\tatexit(SDL_Quit);\n\n\t\/\/ start the PDL library\n\tPDL_Init(0);\n\tatexit(PDL_Quit);\n\n\tPDL_SetOrientation(PDL_ORIENTATION_270);\n\n\tPDL_GetScreenMetrics(&amp;outMetrics);\n\n\t\/\/ Tell it to use OpenGL version 1.0\n\tSDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);\n\tSDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1);\n\n\t\/\/ Set the video mode to full screen\n\tSurface = SDL_SetVideoMode(outMetrics.verticalPixels, outMetrics.horizontalPixels, 0, SDL_OPENGL);\n\n\t\/\/ this is our SDL_Surface which we then use to create the Texture from\n\t\/\/ notice the size of 512 x 512 pixels. Textures has to have a size of 2^x per dimension.\n\t\/\/ We will later only draw in a part of this texture and take care to move and rotate this part into the viewport.\n\tRender = CreateSurface(0, 512, 512);\n\n\t\/\/ setup openGL: 2D orthogonal projection\n\tglClearColor(0.0f, 0.0f, 0.0f, 0.0f);\n\tglViewport( 0, 0, outMetrics.horizontalPixels, outMetrics.verticalPixels );\n\tglMatrixMode(GL_PROJECTION);\n\tglLoadIdentity();\n\tglOrthof(0, outMetrics.horizontalPixels, outMetrics.verticalPixels, 0, -1, 1);\n\n\tglMatrixMode(GL_MODELVIEW);\n\tglLoadIdentity();\n\t\/\/ here we rotate the model to fit in the viewport and move the origin to see it\n\tglRotatef(90, 0, 0, 1);\n\tglTranslatef(0, -outMetrics.horizontalPixels, 0);\n\n\t\/\/ enable 2D textures, vertex arrays, texture arrays and disable depth test\n\tglEnable( GL_TEXTURE_2D );\n\tglEnableClientState(GL_VERTEX_ARRAY);\n\tglEnableClientState(GL_TEXTURE_COORD_ARRAY);\n\tglDisable(GL_DEPTH_TEST);\n\n\t\/\/ create the texture id and use it as active texture for the whole app\n\tglGenTextures(1, &amp;texture);\n\tglBindTexture(GL_TEXTURE_2D, texture);\n<\/code><\/pre>\n<p>3. Now we do the rendering on the SDL_Surface.<\/p>\n<p>Usually we would just render directly on the display surface (the one called Surface in the code above). But we need to create the texture in the size of 2^x<br \/>\ntherefore we render on your offscreen surface, called Render above. We render our objects in the upper left part of the surface.<\/p>\n<p>4. Convert the surface into a texture and render our rectangle with this texture mapped on.<\/p>\n<pre><code>\n\tint mode;\n\n\t\/\/ clear the buffers\n\tglClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);\n\n\t\/\/ we can deal with 2 different display modes here\n\tif (surface-&gt;format-&gt;BytesPerPixel == 3) { \/\/ RGB 24bit\n\t\tmode = GL_RGB;\n\t} else if (surface-&gt;format-&gt;BytesPerPixel == 4) { \/\/ RGBA 32bit\n\t\tmode = GL_RGBA;\n\t}\n\tglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\n\tglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\n\t\/\/ convert our offscreen surface into a texture\n\tglTexImage2D(GL_TEXTURE_2D, 0, mode, surface-&gt;w, surface-&gt;h, 0, mode, GL_UNSIGNED_BYTE, surface-&gt;pixels);\n\n\t\/\/ coordinates for the rectangle and how the texture coordinates fit on it\n\tGLfloat box[] = {0,surface-&gt;h,0, surface-&gt;w,surface-&gt;h,0, surface-&gt;w,0,0, 0,0,0};\n\tGLfloat tex[] = {0,1, 1,1, 1,0, 0,0};\n\tglVertexPointer(3, GL_FLOAT, 0, box);\n\tglTexCoordPointer(2, GL_FLOAT, 0, tex);\n\t\/\/ draw it\n\tglDrawArrays(GL_TRIANGLE_FAN, 0, 4);\n\n\t\/\/ empty caches\n\tglFlush ();\n<\/code><\/pre>\n<p>5. Take care about screen update.<\/p>\n<pre><code>\n\tSDL_GL_SwapBuffers();\n<\/code><\/pre>\n<p>One more point:<br \/>You will notice that the mouse coordinates you get in your event handler are still in portrait, regardless of the landscape mode&nbsp;<br \/>That&#8217;s it.<\/p>\n<p><img src=\"http:\/\/metaviewsoft.de\/wordpress\/wp-content\/uploads\/2010\/09\/Unknown_2010-04-09_090047.jpg\" alt=\"Crimson Fields\"\/><\/p>\n<p>Don&#8217;t forget to check out some of my free apps:<\/p>\n<p><a href=\"http:\/\/developer.palm.com\/appredirect\/?packageid=de.metaviewsoft.crimson\">Crimson Fields<\/a><br \/>\n<a href=\"http:\/\/developer.palm.com\/appredirect\/?packageid=de.metaviewsoft.mandelbrot\">Mandel<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>WebOS in the current version of 1.4.5 has a bug regarding 2D-SDL rendering. Normally, you would create a SDL_Surface, render your object on it and update the screen with help of SDL_Flip() or SDL_UpdateRect() call. This doesn&#8217;t really work on a Pixi: The app works for some seconds and then the screen stops updating. The [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[4],"tags":[],"views":7480,"_links":{"self":[{"href":"https:\/\/metaviewsoft.de\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/459"}],"collection":[{"href":"https:\/\/metaviewsoft.de\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/metaviewsoft.de\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/metaviewsoft.de\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/metaviewsoft.de\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=459"}],"version-history":[{"count":12,"href":"https:\/\/metaviewsoft.de\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/459\/revisions"}],"predecessor-version":[{"id":471,"href":"https:\/\/metaviewsoft.de\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/459\/revisions\/471"}],"wp:attachment":[{"href":"https:\/\/metaviewsoft.de\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=459"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/metaviewsoft.de\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=459"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/metaviewsoft.de\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=459"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}