Jump to content
  • Advertisement
Sign in to follow this  

Questions about drawing in a window with direct draw (2D)

This topic is 3991 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi everyone, First of all forgive my bad english. I am building a 3D engine in c++ (a b-splines cell shading direct rendering using scanlines). I'm using ddraw.lib from directx sdk 9 (converted to libddraw.a with reimp.exe) and MinGW compiler. I started the project in java, but then i noticed that it wasn't the best suited language, so I converted everything in c++. I had no problems converting the classes I created, but I can't understand what's the best way to draw RGB pixels (24 bit, like 0xffffff) to the window surface. My code looks like the following: #define WIDTH 640 #define HEIGHT 480 #include <ddraw.h> #include <windows.h> LRESULT CALLBACK windowProcedure(HWND window, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(window, message, wParam, lParam); } } int WINAPI WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdLine, int cmdShow) { HWND window; MSG message; MSG* messagePointer = &message; WNDCLASSEX windowClass; windowClass.cbClsExtra = 0; windowClass.cbSize = sizeof(WNDCLASSEX); windowClass.cbWndExtra = 0; windowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); windowClass.hCursor = LoadCursor(0, IDC_ARROW); windowClass.hIcon = LoadIcon(0, IDI_APPLICATION); windowClass.hInstance = instance; windowClass.hIconSm = LoadIcon(0, IDI_APPLICATION); windowClass.lpfnWndProc = windowProcedure; windowClass.lpszClassName = "WindowClass"; windowClass.lpszMenuName = 0; windowClass.style = CS_DBLCLKS; RegisterClassEx(&windowClass); RECT desktopRect; GetWindowRect(GetDesktopWindow(), &desktopRect); window = CreateWindowEx(0, "WindowClass", "BSplines3D", WS_OVERLAPPEDWINDOW, (int)((desktopRect.right-WIDTH)/2), (int)((desktopRect.bottom-HEIGHT)/2), WIDTH, HEIGHT, HWND_DESKTOP, 0, instance, 0); ShowWindow(window, SW_SHOW); LPDIRECTDRAW ddraw; DirectDrawCreate(0, &ddraw, 0); ddraw->SetCooperativeLevel(window, DDSCL_NORMAL); LPDIRECTDRAWSURFACE surface; DDSURFACEDESC desc; DDSCAPS caps; memset(&desc, 0, sizeof(desc)); desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; desc.dwFlags = DDSD_CAPS; desc.dwSize = sizeof(desc); ddraw->CreateSurface(&desc, &surface, 0); LPDIRECTDRAWCLIPPER clipper; ddraw->CreateClipper(0, &clipper, 0); clipper->SetHWnd(0, window); surface->SetClipper(clipper); while (GetMessage(messagePointer, 0, 0, 0)) { TranslateMessage(messagePointer); DispatchMessage(messagePointer); } return message.wParam; } The questions are: 1) Is directdraw the best (fastest) way to do this? 2) Is it really necessary to create a primary surface and a back buffer? Wouldn't be simplier (and faster) to draw directly on the primary surface? 3) When and how should I lock the surface and how should I draw into it? I couldn't find clear answers in the FAQs and with google, I hope you can help me. PS: I was reading gamedev.net for a while, but I decided only today to register. I'm glad to be part of this great community :D

Share this post

Link to post
Share on other sites
1) When it comes to putting a 2D object onto the screen, nothing
is faster than DirectDraw. GDI isn't too bad, but its still slower.
And GDI+ is a terrible heap of cr#p. GDI+ has a pretty interface but
speed-wise its worth getting your hands dirty with DirectDraw instead, even
if it is deprecated as there is no real (as in comparable) replacement.

Under the hood I think it is layered over Direct3D these days, but IMHO
if thats how the driver wants to give it hardware acceleration that is
its choice.

However, you mentioned 3D a few times. Are you generating the images
yourself? This is mostly out of interest as I am a software render buff :P
You mentioned scanlines which makes me think so.

2) Yes and no (I'm working from memory here, as my DDraw code is it home
and I am at work right now). I think creating back and primary buffers is
the safe route, however I think with Windowed mode you can actually
create just a primary and write directly to it.

Again, I'll have to get home and check my own code for the details. So I'll
edit/post-again if I have any unsaid info. I know that in my own code
I do it both ways, and it just depends on fullscreen or windowed rendering.

3) As for locking. Look up the DDraw 'Lock' on this link (providing it works,
not too sure about MSDN and cut'n'pasting addressed):
MSDN DirectDraw7 Pages(DirectDrawSurface7)

Hope that helps. Ask again if there is anything else you need or don't
understand. :D


Share this post

Link to post
Share on other sites
What I'm trying to do is a game engine. For the graphic part I want to create my own 3D engine working only with curves (uniformal quadratic b-spline surfaces). I have found a fast method (similar to scanline) to render this kind of curves without using a triagulation algorithm first. With this method I can obtain only a cell shading graphic style. I'm first projecting the 3D objects on 2D, then using the "scanline" algorithm and then drawing everything with DirectDraw.
I was finally able to draw directly on the primary surface and that's really fast (640 (width) x 480 (height) x 32 (bit) x 60 (fps) using less than 1% of the CPU!). I'm using two threads, one for the window messages and the other for the graphic, synchronized with the monitor frame rate (with WaitForVerticalBlank()). This should make sure that no tearing appears, even if I'm drawing on the primary surface. I'll let you know if I'll have problems/errors without using the backbuffer.
Is there a function to get window's size and position? What I'm looking for is a way to be sure to draw INSIDE the window and not ON the window. I mean, I would like to draw just on the blank part of the window and not on the window title bar and borders.

Thank you for your help.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!