{"id":275,"date":"2009-06-12T23:29:00","date_gmt":"2009-06-12T17:59:00","guid":{"rendered":"http:\/\/techtwaddle.net\/?p=275"},"modified":"2015-06-13T21:28:52","modified_gmt":"2015-06-13T15:58:52","slug":"lets-do-some-graphics-directdraw-part-2","status":"publish","type":"post","link":"https:\/\/techtwaddle.co.in\/blog\/2009\/06\/12\/lets-do-some-graphics-directdraw-part-2\/","title":{"rendered":"Lets do some graphics: DirectDraw, Part 2"},"content":{"rendered":"<div style=\"text-align: justify;\">Well, the initial excitement from DDEX1 didn&#8217;t last for long. Just flipping between screens having some text ain&#8217;t much fun. I moved onto DDEX2. DDEX2 pretty much did the same thing as DDEX1 but on a background image. It drew a fancy background on the back buffer and then flipped some alternating text onto it. Nothing too exciting here, so I didn&#8217;t bother trying to make it work on the emulator.DDEX3 turned out to be interesting. It used 4 surfaces in total, a primary surface, a back buffer and two additional surface buffers. The two additional buffers were used to store the upper half and lower half of a bmp image file, respectively. And as and when the timer fired, they Blt one of these buffers onto the back buffer and then flipped the primary surface so that the current image on the back buffer could be displayed. You can check out the bmp file, the upper half says &#8220;Even Screen&#8221; on a blue background and the lower half says &#8220;Odd Screen&#8221; on a red background.As I said before, trying to run DDEX3 directly on emulator was not possible because the emulators do not support back buffers (also known as Complex surfaces, i think) and the program quit with an error message. So obviously the code had to be modified a bit, just like we did for DDEX1, to make it work. Here is how to make it work on an emulator:<br style=\"font-family: Comic Sans MS;\" \/><br \/>\n<br style=\"font-family: Comic Sans MS;\" \/><br \/>\nFirst create a global <em>BOOL<\/em> variable <em>bSingleBuffer<\/em> and initialize it to <em>FALSE<\/em>. As before, comment out the part in <em>InitApp()<\/em> function where after doing <em>GetCaps()<\/em> it fails with an error message saying that the device does not support back buffers. So with that code out of the way, add the following piece of code:<\/p>\n<div style=\"text-align: left; color: #000080;\"><span style=\"color: #0000ff;\">\u00a0\u00a0\u00a0 if (!(ddCaps.ddsCaps.dwCaps &amp; DDSCAPS_BACKBUFFER) || !(ddCaps.ddsCaps.dwCaps &amp; DDSCAPS_FLIP))<\/span><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 <\/span><\/div>\n<div style=\"text-align: left; color: #000080;\"><span style=\"color: #0000ff;\">\u00a0\u00a0\u00a0 {<\/span><\/div>\n<div style=\"text-align: left; color: #000080;\"><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 printf(&#8220;Device does not support backbuffer or flip!\\n&#8221;);<\/span><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 printf(&#8220;Using a normal surface (not a backbuffer)\\n&#8221;);<\/span><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 bSingleBuffer = TRUE;<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 }<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 memset(&amp;ddsd, 0, sizeof(ddsd));<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 ddsd.dwSize = sizeof(ddsd);<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 if(bSingleBuffer)<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 {<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 ddsd.dwFlags = DDSD_CAPS;<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 }<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 else<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 {<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 DDSCAPS_FLIP;<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 ddsd.dwBackBufferCount = 1;<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 }<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 hRet = g_pDD-&gt;CreateSurface(&amp;ddsd, &amp;g_pDDSPrimary, NULL);<\/span><\/p>\n<\/div>\n<p>If the device does not support back buffer or flip then we set the bSingleBuffer variable to TRUE. Then create our primary surface and store the pointer to the surface in g_pDDSPrimary variable. The next part of code gets the back buffer from the primary surface using EnumAttachedSurfaces() function, that part has to be modified as below:<br style=\"font-family: Comic Sans MS;\" \/><br \/>\n<br style=\"font-family: Comic Sans MS;\" \/><br \/>\n<span style=\"color: #000080; font-family: Verdana;\">\u00a0\u00a0\u00a0<\/span><span style=\"color: #0000ff;\"> if(bSingleBuffer)<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 {<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 ddsd.dwWidth = 240;<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 ddsd.dwHeight = 320;<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 hRet = g_pDD-&gt;CreateSurface(&amp;ddsd, &amp;g_pDDSBack, NULL);<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 if(hRet != DD_OK)<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 {<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 return InitFail(hWnd, hRet, TEXT(&#8220;Failed to create normal surface&#8221;));<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 }<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 }<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 else<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 {<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \/\/ Get a pointer to the back buffer<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 hRet = g_pDDSPrimary-&gt;EnumAttachedSurfaces(&amp;g_pDDSBack, EnumFunction);<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 if (hRet != DD_OK)<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 return InitFail(hWnd, hRet, szEnumAttachedSurfacesFailMsg);<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 }<\/span><\/p>\n<p>Here, if bSingleBuffer is set, we create a normal surface, 240 pixels wide and 320 pixels high. The resolution of the emulator. Otherwise we get the back buffer from the primary surface.<\/p>\n<p>Then the two off-screen surfaces are created. This part of code remains the same, the only change is,<\/p>\n<p><span style=\"color: #0000ff;\">\u00a0\u00a0 \/\/ Create a offscreen bitmap.<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 ddsd.dwHeight = 320;<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 ddsd.dwWidth = 240;<\/span><\/p>\n<p>This is same as the original code, only thing I changed here are the height and width.<\/p>\n<p>Next change would be in the InitSurfaces() function,<\/p>\n<p><span style=\"color: #0000ff;\">\u00a0\u00a0\u00a0 DDCopyBitmap(g_pDDSOne, hbm, 0, 0, 240, 320);<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 DDCopyBitmap(g_pDDSTwo, hbm, 0, 320, 240, 320);<\/span><\/p>\n<p>Originally, the bitmap was getting copied from 0, 0, 640, 480 and 0, 480, 640, 480. I think the original program was intended for a VGA resolution device but since the emulator runs Quarter VGA, I modified the dimensions.<\/p>\n<p>The final change is in the WindowProc() function under the WM_TIMER message inside the while loop. The original code simply called Flip() on the primary surface to display the image in the back buffer, and as I have been repeating like a million times, the emulator does not support flipping (: So the original code,<\/p>\n<p><span style=\"color: #0000ff;\">\u00a0\u00a0\u00a0 hRet = g_pDDSPrimary-&gt;Flip(NULL, 0);<\/span><\/p>\n<p>becomes,<\/p>\n<p><span style=\"color: #0000ff;\">if(bSingleBuffer)<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 {<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \/\/RECT src, dest;<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 hRet = g_pDDSPrimary-&gt;Blt(NULL, g_pDDSBack, NULL, 0, NULL);<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 <\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 if(hRet != DD_OK)<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 {<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 printf(&#8220;DDEX3: Blt on primary surface failed, errcode:0x%x\\n&#8221;, GetLastError());<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 }<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 }<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 else<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 {<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 hRet = g_pDDSPrimary-&gt;Flip(NULL, 0);<\/span><\/p>\n<p><span style=\"color: #0000ff;\"> \u00a0\u00a0\u00a0 }<\/span><\/p>\n<p>And that is all! DDEX3 is now ready to be run on the emulator (: Notice that <a href=\"http:\/\/geekswithblogs.net\/TechTwaddle\/archive\/2009\/06\/22\/lets-do-some-graphics-directdraw-part-1.aspx\">last time<\/a> I had used the src and dest RECT&#8217;s to specify the size and location of the source and destination rectangles on the source and destination surfaces respectively. Specifying NULL for both src and dest would make use of the entire source and destination surfaces, which is exactly what we want. The remaning part of the while loop remains same.<\/p>\n<p>The emulator screen now flips between the following two screens every half-second.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignleft size-full wp-image-535\" src=\"https:\/\/www.techtwaddle.co.in\/blog\/wp-content\/uploads\/2009\/06\/img1.png\" alt=\"img1\" width=\"367\" height=\"565\" srcset=\"https:\/\/techtwaddle.co.in\/blog\/wp-content\/uploads\/2009\/06\/img1.png 367w, https:\/\/techtwaddle.co.in\/blog\/wp-content\/uploads\/2009\/06\/img1-195x300.png 195w\" sizes=\"(max-width: 367px) 100vw, 367px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>and<\/p>\n<p>&nbsp;<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignleft size-full wp-image-536\" src=\"https:\/\/www.techtwaddle.co.in\/blog\/wp-content\/uploads\/2009\/06\/img2.png\" alt=\"img2\" width=\"369\" height=\"568\" srcset=\"https:\/\/techtwaddle.co.in\/blog\/wp-content\/uploads\/2009\/06\/img2.png 369w, https:\/\/techtwaddle.co.in\/blog\/wp-content\/uploads\/2009\/06\/img2-195x300.png 195w\" sizes=\"(max-width: 369px) 100vw, 369px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>As you can see, I replaced the stale red and blue screens with something a bit more nice (: Well, obviously you know how to do that. Don&#8217;t you? (:<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Well, the initial excitement from DDEX1 didn&#8217;t last for long. Just flipping between screens having some text ain&#8217;t much fun. I moved onto DDEX2. DDEX2 pretty much did the same thing as DDEX1 but on a background image. It drew a fancy background on the back buffer and then flipped some alternating text onto it. &hellip; <a href=\"https:\/\/techtwaddle.co.in\/blog\/2009\/06\/12\/lets-do-some-graphics-directdraw-part-2\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Lets do some graphics: DirectDraw, Part 2<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false},"categories":[1],"tags":[],"jetpack_featured_media_url":"","jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p1ktFF-4r","_links":{"self":[{"href":"https:\/\/techtwaddle.co.in\/blog\/wp-json\/wp\/v2\/posts\/275"}],"collection":[{"href":"https:\/\/techtwaddle.co.in\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/techtwaddle.co.in\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/techtwaddle.co.in\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/techtwaddle.co.in\/blog\/wp-json\/wp\/v2\/comments?post=275"}],"version-history":[{"count":7,"href":"https:\/\/techtwaddle.co.in\/blog\/wp-json\/wp\/v2\/posts\/275\/revisions"}],"predecessor-version":[{"id":541,"href":"https:\/\/techtwaddle.co.in\/blog\/wp-json\/wp\/v2\/posts\/275\/revisions\/541"}],"wp:attachment":[{"href":"https:\/\/techtwaddle.co.in\/blog\/wp-json\/wp\/v2\/media?parent=275"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/techtwaddle.co.in\/blog\/wp-json\/wp\/v2\/categories?post=275"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/techtwaddle.co.in\/blog\/wp-json\/wp\/v2\/tags?post=275"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}