Jump to content


Starting up with DirectDraw


1 reply to this topic

#1 spoulson

    New Member

  • Members
  • Pip
  • 6 posts

Posted 02 January 2006 - 06:34 PM

It seems I'm stilling having trouble gripping the last few details with using DirectDraw. I'm trying to startup by learning windowed drawing, since I don't have a dual monitor setup to effectively code in full screen.

All I want to do is try to draw an arbitrary pattern of RGB values in the window. I am able to create the IDirectDraw7 *, a primary/back surface, and clipper associated with the app's HWND.

I have trouble when I try to lock the primary surface. I always get the error DDERR_SURFACEBUSY. I am able to lock the back surface and draw to it, but I get an access violation part way through it. I though it didn't create a 32-bit pixel format, so I made sure to state that in the surfacedesc of the back buffer, but it didn't help. I reduced my drawing range to fix it for now. After doing that, I tried blitting to the primary surface, but nothing happens, not even black or random pattern.

Any ideas? Appropriate code is below. (ClientPoint and ClientSize are updated in WndProc with position and size of client window)

// Setup DirectDraw
DirectDrawCreateEx(NULL, (LPVOID *)&dd, IID_IDirectDraw7, NULL);
dd->SetCooperativeLevel(hWnd, DDSCL_NORMAL);

// Get primary surface
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
dd->CreateSurface(&ddsd, &ddPrimary, NULL);

// Create clipper
dd->CreateClipper(0, &ddClipper, NULL);
ddClipper->SetHWnd(0, hWnd);
ddPrimary->SetClipper(ddClipper);

// Create back buffer
ZeroMemory(&ddsdBack, sizeof(ddsd));
ddsdBack.dwSize = sizeof(ddsd);
ddsdBack.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
ddsdBack.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsdBack.dwWidth = 640;
ddsdBack.dwHeight = 480;
ddsdBack.ddpfPixelFormat.dwSize = sizeof(ddsdBack.ddpfPixelFormat);
ddsdBack.ddpfPixelFormat.dwFlags = DDPF_RGB;
ddsdBack.ddpfPixelFormat.dwRGBBitCount = 24;
dd->CreateSurface(&ddsdBack, &ddBack, NULL);

...

// Render display
// Lock surface, get pointer
HRESULT hr = ddBack->Lock(NULL, &ddsdBack, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
if (hr != DD_OK) continue;
DWORD *pSurface = (DWORD *)ddsdBack.lpSurface;
if (pSurface != NULL) {
   // Draw something
   DWORD pixel = (DWORD)RGB(0,0,0);
   for (DWORD y = 0; y < (DWORD)ddsdBack.dwHeight/8; y++) {
      for (DWORD x = 0; x < (DWORD)ddsdBack.dwWidth; x++) {
         DWORD idx = x + (ddsdBack.lPitch * y);
         pSurface[idx] = pixel;
         pixel += 0x100;
      }
   }

   // Blit to primary surface
   RECT rc = {ClientPoint.x, ClientPoint.y, ClientPoint.x+ClientSize.cx, ClientPoint.y+ClientSize.cy};
   DDBLTFX ddbltfx;
   ZeroMemory(&ddbltfx, sizeof(ddbltfx));
   ddbltfx.dwSize = sizeof(ddbltfx);
   ddPrimary->Blt(&rc, ddBack, NULL, 0, &ddbltfx);
}

ddBack->Unlock(NULL);


#2 Nick

    Senior Member

  • Members
  • PipPipPipPip
  • 1227 posts
  • LocationOttawa, Ontario, Canada

Posted 03 January 2006 - 12:58 AM

Check all return values and pointers. Verify that all surfaces do get created.

I also see you're trying to create a 24-bit back buffer. Some hardware doesn't support this mode (but almost all support 32-bit ARGB).





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users