游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2783|回复: 3

请问各位关于DDraw在窗口模式下怎么显示图的问题

[复制链接]

5

主题

54

帖子

62

积分

注册会员

Rank: 2

积分
62
发表于 2006-4-12 20:30:00 | 显示全部楼层 |阅读模式
// 颜色版
PALETTEENTRY          savepalette[256];     // 记录颜色板
DDSURFACEDESC2        ddsd;                  // DDraw表面结构描述
DDBLTFX               ddbltfx;               // 光栅填充结构
DDSCAPS2              ddscaps;               // DX表面功能设置结构
HRESULT               ddrval;                // 用来判断DX创建成功与否
DWORD                 startclockcount = 0; // 记时
//太阳
HBITMAP            bitmapSun;               
//树皮
HBITMAP            bitmapTree;
//树叶
HBITMAP            bitmapLeaf;



//缓冲区域
char buffer[80];     

int gwidth  = -1;

int gheight = -1;
//DDraw关闭标志
int    window_closed      = 0;   
//全局窗口句柄
HWND   hmain= NULL;

HDC    hdcback = NULL ;//后备表面的DC

HDC    hdcmain = NULL ; //主表面DC
//全局实例句柄
HINSTANCE hinstance_app      = NULL;
RECT rcWindow;
//演示开始标志
int BeginDome = 0;

//路径
string strsun = "F:\\毕业设计\\GEngine\\main\\pic\\sun.bmp";

string strTree = "..\\tree1.bmp";
//============================================================
//窗口

HRESULT DestroyObjects()
{
  
    SAFE_RELEASE( lpddsback );
    SAFE_RELEASE( lpddsmain );

    if( lpdd )
        lpdd->SetCooperativeLevel( hmain, DDSCL_NORMAL );

    SAFE_RELEASE( lpdd );

    return S_OK;
}

HRESULT CreateDDrawWindowedDisplay( HWND hWnd, DWORD dwWidth, DWORD dwHeight )
{
    HRESULT hr;

    //清除上一次
    DestroyObjects();

    //开始做表面
    if( FAILED( hr = DirectDrawCreateEx( NULL, (VOID**)&lpdd,
                                         IID_IDirectDraw7, NULL ) ) )
        {
                return E_FAIL;
        }
    // 实质协作模式
    hr = lpdd->SetCooperativeLevel( hWnd, DDSCL_NORMAL );
    if( FAILED(hr) )
        return E_FAIL;

    RECT  rcWork;
    RECT  rc;
    DWORD dwStyle;

   
    dwStyle  = GetWindowStyle( hWnd );

    SetWindowLong( hWnd, GWL_STYLE, dwStyle );

    // 设置尺寸
    SetRect( &rc, 0, 0, dwWidth, dwHeight );

    AdjustWindowRectEx( &rc, GetWindowStyle(hWnd), GetMenu(hWnd) != NULL,
                        GetWindowExStyle(hWnd) );

    SetWindowPos( hWnd, NULL, 0, 0, rc.right-rc.left, rc.bottom-rc.top,
                  SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE );

    SetWindowPos( hWnd, HWND_NOTOPMOST, 0, 0, 0, 0,
                  SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );

    // 保证不会到窗口外
    SystemParametersInfo( SPI_GETWORKAREA, 0, &rcWork, 0 );
   
        GetWindowRect( hWnd, &rc );
   
        if( rc.left < rcWork.left ) rc.left = rcWork.left;
   
        if( rc.top  < rcWork.top )  rc.top  = rcWork.top;
   
        SetWindowPos( hWnd, NULL, rc.left, rc.top, 0, 0,
                  SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
//
    LPDIRECTDRAWCLIPPER pcClipper;
   

    DDSURFACEDESC2 ddsd;
    ZeroMemory( &ddsd, sizeof( ddsd ) );
    ddsd.dwSize         = sizeof( ddsd );
    ddsd.dwFlags        = DDSD_CAPS;
    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

    if( FAILED( lpdd->CreateSurface( &ddsd, &lpddsmain, NULL ) ) )
        return E_FAIL;

    // 创建离屏表面
    ddsd.dwFlags        = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;   
    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
    ddsd.dwWidth        = dwWidth;
    ddsd.dwHeight       = dwHeight;

    if( FAILED( hr = lpdd->CreateSurface( &ddsd, &lpddsback, NULL ) ) )
        return E_FAIL;

    if( FAILED( hr = lpdd->CreateClipper( 0, &pcClipper, NULL ) ) )
        return E_FAIL;

    if( FAILED( hr = pcClipper->SetHWnd( 0, hWnd ) ) )
    {
        pcClipper->Release();
        return E_FAIL;
    }

    if( FAILED( hr = lpddsmain->SetClipper( pcClipper ) ) )
    {
        pcClipper->Release();
        return E_FAIL;
    }

    //销毁剪切器
    pcClipper->Release();

   
    bitmapSun = (HBITMAP)LoadImage(hinstance_app , strsun.data() , IMAGE_BITMAP , 148 , 144 ,
                                            LR_LOADFROMFILE);
       
   
       
    UpdateBounds();

    return S_OK;
}


HRESULT UpdateBounds()
{
    if( hmain )
    {
        GetClientRect( hmain, &rcWindow );
        ClientToScreen( hmain, (POINT*)&rcWindow );
        ClientToScreen( hmain, (POINT*)&rcWindow+1 );
    }
    else
    {
        SetRect( &rcWindow, 0, 0, GetSystemMetrics(SM_CXSCREEN),
                 GetSystemMetrics(SM_CYSCREEN) );
    }

    return S_OK;
}
int DrawTextGDI(char *text, int x,int y,COLORREF color, LPDIRECTDRAWSURFACE7 lpdds)
{
        //用来画一些文字,DDraw画文字很不好话,所以用DDraw的GDI 来画
       
        HDC dc; //设备DC
       
        //从表面得到DC
        if (FAILED(lpdds->GetDC( &dc )))
                return(0);
       
        //设置文本颜色
        SetTextColor(dc,color);
       
        //设置北京是否透明
        SetBkMode(dc, TRANSPARENT);
       
        //调用GDI的绘画函数
        TextOut(dc,x,y,text,strlen(text));
       
        // 释放DC
        lpdds->ReleaseDC(dc);
       
        return(1);
}
//窗口过程
LRESULT CALLBACK EGWndProc(
                                                   HWND hwnd,
                                                   UINT msg,
                                                   WPARAM wp,
                                                   LPARAM lp
                                                   )
{
        PAINTSTRUCT ps;//打印结构
        HDC hdc;//设备句柄
       
        switch(msg)
        {
        case WM_CREATE:
                {
                        return 0;
                }
                break;
        case WM_PAINT:
                {//在这里是重点,以后所有的图可能都在这里了
                        hdc = BeginPaint(hwnd , &ps);
                       
                        EndPaint(hwnd , &ps);
                        return 0;
                }
                break;
        case WM_LBUTTONDOWN:
                {
                        return 0;
                }
                break;
        case WM_TIMER:
                {//定时在这里开始
                        return 0;
                }
                break;
        case WM_CHAR:
                {
                        return 0;
                }
                break;
        case WM_KEYUP:
                {//响应键盘
                        return 0;
                }
               
        case WM_KEYDOWN:
                {
                        int VCode = (int)wp;//解析键盘消息
            int keyState = (int)lp;//解析键盘状态
                       
                       
                }
                break;
        case WM_MOVE:
                {  
                        return 0;
                }
                break;
        case WM_COMMAND:
                {
                        int ctrlID = LOWORD(wp);
                        HWND hwnd  = (HWND)lp;
                       
                        switch(ctrlID)
                        {
                        case ID_IMAGESELDLG:
                                {
                                        DialogBox(hinstance_app , MAKEINTRESOURCE(IDD_DIALOG) , NULL , EGDlgProc);
                                        return 0;
                                }
                                break;
                        case ID_MUCIS_OPEN:
                                {
                                        PlaySound(MAKEINTRESOURCE(IDR_MUSIC1),
                                                hinstance_app, SND_RESOURCE | SND_ASYNC);
                                        return 0;
                                }
                                break;
                        case ID_MUSIC_CLOSE:
                                {
                                       
                                        PlaySound(NULL , hinstance_app , SND_PURGE);
                                        return 0;
                                }
                        case ID_BEGINDOME:
                                {
                    BeginDome = 1;
                                        return 0;
                                }
                                break;
                        case ID_ENDDOME:
                                {
                                        BeginDome = 0;
                                        return 0;
                                }
                               
                        default:break;
                        }
            return 0 ;
                }
                break;
        case WM_DESTROY:
                {
            PostQuitMessage(0);
                        return 0;
                }
        case WM_SIZE:
                {
                       
                }
        default:break;
        }
        return DefWindowProc(hwnd , msg , wp, lp);
       
}
//=================================================================================
//对话框过程
BOOL CALLBACK EGDlgProc(
                                                HWND hDlg,
                                                UINT Dlgmsg,
                                                WPARAM wpDlg,
                                                LPARAM lpDlg
                                                )
{
        switch (Dlgmsg)
        {
        case WM_INITDIALOG:
                {       
                        return TRUE;
                }
        case WM_COMMAND:
                {
                                                                          
                        if (LOWORD(wpDlg) == IDOK || LOWORD(wpDlg) == IDCANCEL)
                        {
                                EndDialog(hDlg, LOWORD(wpDlg));
                                return TRUE;
                        }
                }
                break;
        }
        return FALSE;
}
//
int EGInit()
{
            
   // DDrawCreateSurface(800 , 600 , NULL , 1);
   
        HDC dcImage;
        CreateDDrawWindowedDisplay(hmain , 800 , 600 );

        lpddsback->GetDC(&hdcback);
       
    dcImage = CreateCompatibleDC(hdcback);

        SelectObject(dcImage , bitmapSun);

        BitBlt(hdcback , 0 , 0 , 148 , 144 , dcImage , 0 , 0 , SRCCOPY);

        lpddsback->ReleaseDC(hdcback);
        return(1);
       
}

int EGmain()
{
       
       
    CGERect EGrectclient;//窗口的范围
       
        lpddsmain->BltFast(0 , 0 , lpddsback , &rcWindow ,NULL);
        Sleep(30);

   return 0;

       
}

////////////////////////////////////////////////////////////



/////////////////////////////////////////////////////////////

int EGShutdown(void *parms = NULL, int num_parms = 0)
{
        // 把所有和这次创建有关的东西全部释放了
       
       
       
       
        if (lpddsmain)
        {
                lpddsmain->Release();
                lpddsmain = NULL;
        }
       
        //释放Draw接口指针
        if (lpdd)
        {
                lpdd->Release();
                lpdd = NULL;
        }
        return(1);
       
}
//===============================================================================
int WINAPI WinMain(        HINSTANCE hinstance,
                                   HINSTANCE hprevinstance,
                                   LPSTR lpcmdline,
                                   int ncmdshow)
{
       
        HWND mainwnd;//窗口句柄
       
        MSG msg;//消息
       
        WNDCLASSEX EGwindow;//创建一个主窗口类
       
        EGwindow.cbSize        = sizeof(WNDCLASSEX);
        EGwindow.style         = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
        EGwindow.lpfnWndProc   =   EGWndProc;
        EGwindow.cbClsExtra    = 0;
        EGwindow.cbWndExtra    =  0;
        EGwindow.hInstance     = hinstance;
        EGwindow.hIcon         = LoadIcon(NULL , IDI_APPLICATION);
        EGwindow.hCursor       = LoadCursor(NULL , IDC_ARROW);
        EGwindow.hbrBackground = GetStockBrush(LTGRAY_BRUSH);
        EGwindow.lpszMenuName  = NULL;//以后加
        EGwindow.lpszClassName = WINDOWEGCLASS;
        EGwindow.hIconSm       = LoadIcon(NULL , IDI_APPLICATION);
       
        hinstance_app = hinstance;
        if(!RegisterClassEx(&EGwindow))
        {//注册窗口类
                return 0;
        }
       
        mainwnd = CreateWindowEx(   
                NULL,
                WINDOWEGCLASS,
                "EG图象引擎",
                WS_VISIBLE | WS_CAPTION  | WS_SYSMENU | WS_MINIMIZEBOX ,
                120 , 60 , 800 , 600,
                NULL,
                LoadMenu(hinstance , MAKEINTRESOURCE(IDR_MAINMENU)),
                hinstance,
                NULL);
       
        hmain = mainwnd;
        //这里处初始化
        EGInit();
        while(1/*GetMessage(&msg , NULL , 0 , 0)*/)
        {
                if(PeekMessage(&msg , NULL , 0 , 0 , PM_REMOVE))
                {
                        if(msg.message == WM_QUIT)
                        {
                                break;
                        }
                }
                TranslateMessage(&msg);
               
                DispatchMessage(&msg);
               
                EGmain();//这里不断运行函数
        }
       
        EGShutdown();//关闭
        return (msg.wParam);

如上,我的做法的做一个主表面一个离屏表面,然后倒入位图,得到离屏的DC把位图弄上去,
在用bltfast拷贝到主表面可为什么我检查没错各变量也对,但就是窗口上什么都没有!老大们帮一下明天就要交了!谢谢

38

主题

275

帖子

281

积分

中级会员

Rank: 3Rank: 3

积分
281
QQ
发表于 2006-4-12 21:36:00 | 显示全部楼层

Re:请问各位关于DDraw在窗口模式下怎么显示图的问题

  你的代码---乱!  没有细看代码,只是看了下你的WinMain。
  我觉得,你把渲染函数的调用放在消息处理里,不妥当。一般的主循环为:
  while(1)
{
     if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
    {
            if(msg.message==WM_QUIT)   
                  break;
           TranslateMessage(&msg);
           DispatchMessage(&msg);
     }
     else
       if(bWindowActive)
       {
               Render();             //渲染
       }
}

86

主题

2251

帖子

2386

积分

金牌会员

Rank: 6Rank: 6

积分
2386
QQ
发表于 2006-4-13 00:46:00 | 显示全部楼层

Re:请问各位关于DDraw在窗口模式下怎么显示图的问题

代码贴出会被过滤掉一些空格,建议用code标签:

  1. [code]。。。
复制代码
[/code]

72

主题

447

帖子

454

积分

中级会员

Rank: 3Rank: 3

积分
454
QQ
发表于 2006-4-14 15:45:00 | 显示全部楼层

Re:请问各位关于DDraw在窗口模式下怎么显示图的问题

不要贴一些无关紧要的代码,把主要的部分贴上来就可以了,这么长真的很难有耐性看完

一般2D不显示的问题总会出现在绘制区域上:要么绘制出来的图片是一张空图,要么把图片绘制到窗口外面去了,更隐的蔽错误是绘制上了一张全透明图片(这是ID3DXSPRITE里常犯的错误)。

---------------------------------------
2D游戏制作论坛
http://www.dingge.com/forum/index.asp
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-24 05:28

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表