Skip to main content
gamedev.net
🔒 Locked

Problem in DirectX Code

Started by IronmanDM670 2 replies 1.2k views
Original Post
IronmanDM670
IronmanDM670
I am working out of a Sam's DirectX7 book and using Dev-C plus plus 4.9.9.2, I have programmed console applications before but am trying to learn Win API and DirectX. This code is supposed to load and display a bitmap within a window. Instead it seems to take the full screen and displays black across the board. If you can see anything out of the ordinary please let me know.

/***************************************************************
*                                                              *
*   Author:                  John Doe                          *
*                                                              *
*   Program:                 Sam's DirectX7 Tutorial Chp2      *
*   Start DATE:              May 30, 2007                      *
*   Completion Date:         December 9, 9999                  *
*   Purpose:                                                   *
*      This program loads a bitmap, creates a primary surface  *
*      then displays it to the screen within a window.         *
*      Menu commands: FILE                                     *
*                         -exit                                *
*                                                              *
*   Program Input:                                             *
*                                                              *
*                                                              *
*   Program Output:                                            *
*                                                              *
*                                                              *
***************************************************************/

#include "stdafx.h"
#include "resource.h"
#define INITGUID

#define SafeRelease(x) if(x) {x->Release(); x = NULL;}

#include <ddraw.h>

// Image Loading and Inititalization Flags //
BOOL bInit = FALSE;

// Global Interface Pointers //

//DirectDraw Object// 
LPDIRECTDRAW7          lpDD = NULL; 
//DirectDraw-PrimarySurface//
LPDIRECTDRAWSURFACE7    lpDDSPrimary = NULL;
//DirectDraw Clipper Object//
LPDIRECTDRAWCLIPPER    lpClip = NULL;
//Bitmap Suface//
LPDIRECTDRAWSURFACE7    lpBmp = NULL;
// Windows Class Information //
static char szClass[] = "XmplHr2Class";
static char szCaption[] = "Example - Hour 2";
// Error Return String //
const char* ErrStr = NULL;
// Error Messages // 

const char Err_Reg_Class[] = "Error Registering Window Class";
const char Err_Create_Win[] = "Error Creating Window";
const char Err_DirectDrawCreate[] = "DirectDrawCreate FAILED";
const char Err_Query[] = "QueryInterface FAILED";
const char Err_Coop[] = "SetCooperativeLevel FAILED";
const char Err_CreateClip[] = "createClip FAILED";
const char Err_CreateSurf[] = "CreateSurface FAILED";
const char Err_LoadBMP[] = "Error Loading Image";

static BOOL Init(HINSTANCE hInstance, int nCmdShow);
void Cleanup(void);
void DrawImage();
LRESULT CALLBACK WindowProc(HWND hWnd, unsigned uMsg, WPARAM wParam, LPARAM lParam);
LPDIRECTDRAWSURFACE7 bitmap_surface(LPCTSTR file_name);

// Windows Main Function // 

int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    //windows message structure//
    MSG msg;
    
    //Initialize the Appilication, Exit on Failure//
    if(!Init(hInstance, nCmdShow))
    {
        Cleanup();
        return FALSE;
    }
    //handle the message loop until exit//
    while(GetMessage(&msg, NULL, NULL, NULL))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    //exit returning final message//
    return(msg.wParam);
}

static BOOL Init(HINSTANCE hInstance, int nCmdShow)
{
    WNDCLASS wc;
    HRESULT hRet;
    DDSURFACEDESC2 ddsd;
    
    //set up and register window class//
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = (WNDPROC)WindowProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = sizeof(DWORD);
    wc.hInstance = hInstance;
    wc.hIcon = NULL;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wc.lpszClassName = szClass;
    if(!RegisterClass(&wc))
    {
        ErrStr = Err_Reg_Class;
        return FALSE;
    }
    
    //get dimensions of the screen//
    int ScreenWidth = GetSystemMetrics(SM_CXSCREEN);
    int ScreenHeight = GetSystemMetrics(SM_CYSCREEN);
    //create a window display//
    HWND hWnd;
    hWnd = CreateWindow(szClass, szCaption, WS_VISIBLE|WS_POPUP, 0, 0, ScreenWidth, ScreenHeight, NULL, NULL, hInstance, NULL);
    if(!hWnd)
    {
        ErrStr = Err_Create_Win;
        return FALSE;
    }
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    
    //create the main direct draw object//
    hRet = DirectDrawCreateEx(NULL, (LPVOID*)&lpDD, IID_IDirectDraw7, NULL);
    if(hRet != DD_OK)
    {
        ErrStr = Err_DirectDrawCreate;
        return FALSE;
    }
    
    //set cooperative level//
    hRet = lpDD->SetCooperativeLevel(hWnd, DDSCL_NORMAL);
    if(hRet != DD_OK)
    {
        ErrStr = Err_Coop;
        return FALSE;
    }
    
    //create clipper//
    hRet = lpDD->CreateClipper(NULL, &lpClip, NULL);
    if(hRet != DD_OK)
    {
        ErrStr = Err_CreateClip;
        return FALSE;
    }
    lpClip->SetHWnd(0, hWnd);
    
    //create the primary surface//
    ZeroMemory(&ddsd, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_CAPS;
    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
    hRet = lpDD->CreateSurface(&ddsd, &lpDDSPrimary, NULL);
    if(hRet != DD_OK)
    {
        ErrStr = Err_CreateSurf;
        return FALSE;
    }
    
    //set the clipper for the promary surface//
    lpDDSPrimary->SetClipper(lpClip);
    //flag initialization as completed//
    bInit = TRUE;
    
    //load the default bitmap//
    lpBmp = bitmap_surface("vista.bmp");
    //display the image//
    DrawImage();
    return TRUE;
}

void DrawImage()
{
    //return if not ready to draw at this time//
    if(!lpBmp||!bInit)
        return;
    //draw the image full screen//
    lpDDSPrimary->Blt(NULL, lpBmp, NULL, DDBLT_WAIT, NULL);
    return;
}

LRESULT CALLBACK WindowProc(HWND hWnd, unsigned uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
        case WM_COMMAND:
             switch(LOWORD(wParam))
             {
                 case IDM_EXIT:
                      DestroyWindow(hWnd);
                      break;
             }
        break;
        
        case WM_PAINT:
             PAINTSTRUCT ps;
             
             BeginPaint(hWnd, &ps);
             DrawImage();
             EndPaint(hWnd, &ps);
             break;
             
        case WM_DESTROY:
             Cleanup();
             PostQuitMessage(0);
             break;
             
        default:
                return DefWindowProc(hWnd, uMsg, wParam, lParam);
    } 
                
    return 0L;
}

void Cleanup(void)
{
    //release the interfaces//
    SafeRelease(lpBmp);
    SafeRelease(lpDDSPrimary);
    SafeRelease(lpClip);
    SafeRelease(lpDD);
    //display error if one thrown//
    if(ErrStr)
        MessageBox(NULL, ErrStr, szCaption, MB_OK);
    return;
}

LPDIRECTDRAWSURFACE7 bitmap_surface(LPCTSTR file_name)
{
    HDC hdc;
    HBITMAP bit;
    LPDIRECTDRAWSURFACE7 surf;
    //load the interface
    
    bit = (HBITMAP) LoadImage(NULL, file_name, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE|LR_LOADFROMFILE);
    //if failed to load, return failure to caller
    if(!bit)
        return NULL;
    //get bitmap dimensions
    
    BITMAP bitmap;
    GetObject(bit, sizeof(BITMAP), &bitmap);
    int surf_width = bitmap.bmWidth;
    int surf_height = bitmap.bmHeight;
    
    //create surface
    
    HRESULT ddrval;
    DDSURFACEDESC2 ddsd;
    ZeroMemory(&ddsd, sizeof(ddsd));
    ddsd.dwSize = sizeof(DDSURFACEDESC2);
    ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
    ddsd.dwWidth = surf_width;
    ddsd.dwHeight = surf_height;
    
    //attempt to create surface
    
    ddrval = lpDD->CreateSurface(&ddsd, &surf, NULL);
    
    // created ok?
    
    if(ddrval != DD_OK)
    {
        //no, release the bitmap and return failure to caller
        DeleteObject(bit);
        return NULL;
    }
    else
    {
        //yes, get a DC for the surface
        surf->GetDC(&hdc);
    }
    //generate a compatible DC
    HDC bit_dc = CreateCompatibleDC(hdc);
    //blit the interface to the surface
    SelectObject(bit_dc, bit);
    BitBlt(hdc, 0, 0, surf_width, surf_height, bit_dc, 0, 0, SRCCOPY);
    //release the DCs
    surf->ReleaseDC(hdc);
    DeleteDC(bit_dc);
    //clear bitmap
    DeleteObject(bit);
    //return pointer to caller
    return surf;
}

Here is my header file "resource",

#define IDR_MENU 102
#define IDM_EXIT 4001

and my resource file EXAMPLH2.

#include "resource.h"

IDR_MENU MENU DISCARDABLE
BEGIN
     POPUP "&File"
     BEGIN
          MENUITEM "E&xit", IDM_EXIT
     END
END

ET3D
ET3D
If you really want to learn Windows programming and DirectX I'd suggest:

- Use Visual Studio 2005 Express (with the Platform SDK)
- Use DirectX 9 (or 10)

Using a DirectX version that's been deprecated since 2000 will mean that you get very little help (since few people use it), and using a non-Microsoft development environment is also asking for trouble. It's not that it's impossible to use other things, but I think it's an unnecessary complication.
kVandaele
kVandaele
It sounds like you're just not drawing anything. It's not that it's drawing your tile black, you just clear your backbuffer (with "ZeroMemory(&ddsd, sizeof(ddsd));" if i'm not mistaken) and then your image either just doesn't get drawn, or gets drawn offscreen. That's too much code to wade through though... please read the FAQs: http://www.gamedev.net/community/forums/showfaq.asp?forum_id=10

The FAQs also contain some info on why not to use DirectX7 (of which DirectDraw is a part of), and what to use instead (ID3DSprite with DX9/10). Using DX7 is like using Win95 - it'll still work, for the most part, but (almost) nobody wants it. I think it doesn't even run fine on Vista anymore though, but i'm not sure about that.
Note: if you use sprites, use images with a size the power of 2 (2, 4, 8, 16, 32, 64, 128, 256, ...)

As for a compiler, use what you prefer. I'll second that Visual Studio is awesome, but you should use whichever you prefer...
IronmanDM670
IronmanDM670
Ok, thanks on both accounts. Yes I understand that DirectX7 is a bit outdated. I'm looking into getting a more updated book. I'm just working with what I have. I have access to DirectX 9.0c within my compiler.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.