游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2691|回复: 6

用DirectX9.0c(Feb 2011)写的程序build能过运行会崩溃,求助

[复制链接]

1

主题

3

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2011-3-7 14:11:00 | 显示全部楼层 |阅读模式
我很茫然。build能过,但是run起来的时候,会在Game_Main下的Lock那里中断,并抛出exception:

Unhandled exception at 0x00414115 in T3DEngine.exe :0xC0000005: Access violation reading location 0x00000000

不知道问题出在哪。我用的是Direct9.0c(Feb 2010)的SDK。
求赐教

//engine practice
#define WIN32_LEAN_AND_MEAN //say no to MFC

#define INITGUID //make sure Direct GUID are included

//includes/////////////////////////////
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>

#include <conio.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <malloc.h>
#include <memory.h>
#include <string.h>
#include <stdarg.h>
#include <io.h>
#include <fcntl.h>

#include <ddraw.h> //include direct head
using namespace std;//adding c++ stuffs

//DEFINES/////////////////////////////
//class name
#define WINDOW_CLASS_NAME "WNDCLASS1"

//window size
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define SCREEN_BPP 8
#define SCREEN_MAX_COLOR 256

//TYPES////////////////////////////////
typedef unsigned char BYTE;
typedef unsigned char UCHAR;
typedef unsigned short USHORT;
typedef unsigned short WORD;

//MACROS///////////////////////////////
//
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000)? 1 : 0)
#define KEYUP(vk_code)         ((GetAsyncKeyState(vk_code) & 0x8000)? 0 : 1)

#define DD_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct));ddstruct.dwSize = sizeof(ddstruct); }

//GLOBALS//////////////////////////////
HINSTANCE hInstance_app                = NULL; //save the app
HWND MainWindowHandle                = NULL; //save the main handle

//direct stuff
LPDIRECTDRAW7                        lpdd                        = NULL;//dd object
LPDIRECTDRAWSURFACE7        lpddsprimary        = NULL;//primary surface
LPDIRECTDRAWSURFACE7        lpddsback                = NULL;//back surface
LPDIRECTDRAWPALETTE                lpddpal                    = NULL;//a pointer to the created dd
LPDIRECTDRAWCLIPPER                lpddclipper            = NULL;//clipper of directdraw
PALETTEENTRY                        Palette[256];                   // color palette
PALETTEENTRY                        SavePalette[256];
DDSURFACEDESC2                        ddsd;                                   //a directdraw description
DDBLTFX                                        ddbltfx;                           // use to fill
DDSCAPS2                                ddscaps2;                           //a directdraw surface capbility structure
HRESULT                                        ddrval;                                   //result back for dd call
DWORD                                        start_clock_count = 0; // used for timing

//FUNCTIONS///////////////////////////
LRESULT CALLBACK WindowProc(HWND hwnd,
                                                        UINT msg,
                                                        WPARAM wParam,
                                                        LPARAM lParam)
{
        PAINTSTRUCT ps;//used into WM_PAINT
        HDC hdc;//handle to device context

        //what the message is
        switch(msg)
        {
        case WM_CREATE:
                {
                        //do your init here

                        //return success
                        return (0);
                }break;
        case WM_PAINT:
                {
                        hdc = BeginPaint(hwnd,&ps);

                        //do your paint operation here
                        EndPaint(hwnd,&ps);

                        //return success
                        return (0);
                }break;
        case WM_DESTROY:
                {
                        //send the WM_QUIT
                        PostQuitMessage(0);

                        //return success
                        return (0);
                }break;
        default:break;
        }//end switch

        //return to default windows
        return (DefWindowProc(hwnd,msg,wParam,lParam));
}//end winproc

int Game_Main(void *parm = NULL, int NumParms = 0)
{
        //Main loop of your game.
        if(KEYDOWN(VK_ESCAPE))
                SendMessage(MainWindowHandle,WM_CLOSE,0,0);

        //return success or failure or your own code

        //plot 1000 random pixel to the primary surface and return
        //clear ddsd and set size , never assume it's clean

        //clear and set the size
        memset(&ddsd,0,sizeof(ddsd));
        ddsd.dwSize = sizeof(ddsd);

        //lock the work memory
        lpddsprimary->Lock(NULL, &ddsd,
                   DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,
                   NULL);//debug的时候就停在这行,不用debug直接运行的话也是死在这。
   
        //now ddsd.lPitch is valid and so is ddsd.lpsurface

        //make a couple aliases to make code cleaner, so we don't have to cast

        int mempitch=(int)ddsd.lPitch;
        UCHAR *video_buffer=(UCHAR *)ddsd.lpSurface;

        //plot 1000 random pixels with random color on the
        //primary surface, they will be instantly visible
        for(int index = 0; index < 1000; index ++)
        {
                //select random position and color for 1024x768x8
                UCHAR color = rand()%256;
                int x = rand()%640;
                int y = rand()%480;

                //plot the pixel
                video_buffer[x+y*mempitch] = color;
        }//end for

       
       
        //so we finish drawing, we can unlock it
        if(FAILED(lpddsprimary->Unlock(NULL)))
                return (0);

        //sleep a bit
        Sleep(30);
       
        return (1);

}//end gamemain

int Game_Init(void *parm = NULL, int NumParms = 0)
{
        //do the initialize before your game here
        //Create DirectDraw
        if(FAILED(DirectDrawCreateEx(NULL,(void **)lpdd,IID_IDirectDraw7,NULL)))
                return (0);

        //set the cooperative level to fullscreen
        if(FAILED(lpdd->SetCooperativeLevel(MainWindowHandle,
                                                                          DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX |
                                      DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))
        {
                //error
                return (0);
        }

        if(FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,0,0)))
        {
                //error
                return (0);
        }
        //return success or failure or your own code
        return (1);

        //display picture
        //clear the structure
        memset(&ddsd,0,sizeof(ddsd));

        //so I can fill the struct now
        ddsd.dwSize = sizeof(ddsd);

        //fill the control part. this valid the caps option
        ddsd.dwFlags = DDSD_CAPS;
       
        //fill the caps opton
        ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

        //create the surface
        if(FAILED(lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL)))

                return (0);

        //
        //operation about palette
        //fill em up with color!
        for(int color = 1; color < 255; color++)
        {
                Palette[color].peBlue = rand()%256;
                Palette[color].peRed = rand()%256;
                Palette[color].peGreen = rand()%256;

                //set flag filed to PC_NOCOLLAPSE
                Palette[color].peFlags = PC_NOCOLLAPSE;
        }// end for color

        //fill with the start and the end
        Palette[0].peBlue = 0;
        Palette[0].peRed = 0;
        Palette[0].peGreen = 0;
        Palette[0].peFlags = PC_NOCOLLAPSE;

        Palette[255].peRed = 255;
        Palette[255].peBlue = 255;
        Palette[255].peGreen =255;
        Palette[255].peFlags = PC_NOCOLLAPSE;

        //create the palette
        if(FAILED(lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE,Palette,&lpddpal,NULL)))
                return (0);

        //select your palette
        if(FAILED(lpddsprimary->SetPalette(lpddpal)))
                return (0);
        //So after create directdraw and set co-work with windows
        //What I need to do is setup a palette(remember fill it with
        //random.After that create the canvas——surface which we use
        //for drawing. And use your surface choose your palette. All
        //the initialize work done here(for now)
}//end gameinit

int Game_Shutdown(void *parm = NULL, int NumParms = 0)
{
        //do the sweep work after running
        //release the used device
        if(lpddpal)
        {
                lpddpal->Release();
                lpddpal = NULL;
        }
       
        if(lpddsprimary)
        {
                lpddsprimary->Release();
                lpddsprimary = NULL;
        }

        if(lpdd)
        {
                lpdd->Release();
                lpdd = NULL;
        }


        //return success or failure or your own code
        return (1);
}// end game shutdown

//WINMAIN///////////////////////////
int WINAPI WinMain(HINSTANCE hInstance,
                                   HINSTANCE hPrevInstance,
                                   LPSTR lpCmdLine,
                                   int nShowCmd)

{
        WNDCLASSEX wndclass;//announce a window class
        HWND hwnd;
        MSG msg;
        HDC hdc;//handle to device context

        wndclass.cbSize = sizeof(WNDCLASSEX);
        wndclass.cbClsExtra = 0;
        wndclass.cbWndExtra = 0;
        wndclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
        wndclass.hInstance = hInstance;
        wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
        wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
        wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
        wndclass.lpfnWndProc = WindowProc;
        wndclass.lpszClassName = WINDOW_CLASS_NAME;
        wndclass.lpszMenuName = "NULL";
        wndclass.hIconSm = LoadIcon(NULL,IDI_APPLICATION);

        //save the hinstance in global
        hInstance_app = hInstance;

        //register the window
        if(!(RegisterClassEx(&wndclass)))
                return (0);

        //create the window
        if(!(hwnd = CreateWindowEx(NULL,
                                                            WINDOW_CLASS_NAME,
                                                                "T3D Engine",
                                                                WS_POPUP | WS_VISIBLE,
                                                                0,0,
                                                                SCREEN_WIDTH,SCREEN_HEIGHT,
                                                                NULL,
                                                                NULL,
                                                                hInstance,
                                                                NULL)))
                return (0);
       
        //save the window handle
        MainWindowHandle = hwnd;

        //initialize the game
        Game_Init();

        //go to message loop
        while(TRUE)
        {
                if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
                {
                        if(msg.message == WM_QUIT)
                                break;

                        //translate the message
                        TranslateMessage(&msg);

                        //dispatch the message
                        DispatchMessage(&msg);

                        //call GameMain for every frame
                        Game_Main();
                }//end if
               
        }//end while

        //shutdown the game
        Game_Shutdown();
        //return success
        return (msg.wParam);

}//end winmain

33

主题

159

帖子

272

积分

中级会员

Rank: 3Rank: 3

积分
272
QQ
发表于 2011-3-8 12:24:00 | 显示全部楼层

Re:用DirectX9.0c(Feb 2011)写的程序build能过运行会崩溃,求助

你是不是忘记把 模型文件xfile和 fx文件这些个程序里要用到的文件放到 可执行文件的目录里了?

6

主题

106

帖子

237

积分

中级会员

Rank: 3Rank: 3

积分
237
发表于 2011-3-8 17:29:00 | 显示全部楼层

Re:用DirectX9.0c(Feb 2011)写的程序build能过运行会崩溃,求助

加点日志呗

6

主题

106

帖子

237

积分

中级会员

Rank: 3Rank: 3

积分
237
发表于 2011-3-8 17:38:00 | 显示全部楼层

Re:用DirectX9.0c(Feb 2011)写的程序build能过运行会崩溃,求助

哦,已经可以判断出错的语句了。
是主表面锁定语句出错是吧,看异常信息是访问了NULL指针的值。

是《WINDOWS游戏编程大师技巧》中的代码吧?我之前运行配套的代码没出过这样的问题。直接编译并运行配套代码看看?
另外我记得game_main函数应该在
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{}的外面的。

推荐你看看这本书前面关于DirectX版本的要求,如果使用DirectDraw则需要使用7或8的版本。

1

主题

3

帖子

0

积分

新手上路

Rank: 1

积分
0
 楼主| 发表于 2011-3-10 13:44:00 | 显示全部楼层

Re:用DirectX9.0c(Feb 2011)写的程序build能过运行会崩溃,求助

D3D9里保留了原来的ddraw.lib,所以DDraw是可以用的。
示例程序运行是OK的,可以build过也可以run。但是我自己写的就不行。Game_Main我拿出来了,但是还是会在那里crash掉。

11

主题

1238

帖子

1782

积分

金牌会员

Rank: 6Rank: 6

积分
1782
发表于 2011-3-10 14:04:00 | 显示全部楼层

Re:用DirectX9.0c(Feb 2011)写的程序build能过运行会崩溃,求助

调试

1

主题

3

帖子

0

积分

新手上路

Rank: 1

积分
0
 楼主| 发表于 2011-3-10 14:16:00 | 显示全部楼层

Re:用DirectX9.0c(Feb 2011)写的程序build能过运行会崩溃,求助

查出问题了……
if(FAILED(DirectDrawCreateEx(NULL,(void **)lpdd,IID_IDirectDraw7,NULL)))
return (0);

在创建DirectDraw的时候,给的应该是一个lpdd的LPVOID型指针,我漏掉了“&“,应该是(void **)&lpdd

谢谢大家~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-6-7 17:30

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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