我正在自学DirectX SDK9.0,用VC++6。0 编了一小程序,运行结果是一个旋转的矩形。经过一番努力终于成功了。
按快捷键F7 编译无错,按F5后也能运行,与设想没差别。但是,按Ctrl+F5后显示器一闪之后就出现“3d.exe 遇到问题需要关闭。我们对此引起的不便表示抱歉。”的对话框,还有发送错误报告之类的,直接运行/Dubug中的.exe也出现一样的结果,我学编程两年多第一次遇到,身边也无人能解决。哪位高人能一语道破天机,在下感激不尽。。。。。。
代码如下
#include <windows.h>
#include <fstream.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <math.h>
LPDIRECT3D9 pd3d;
LPDIRECT3DDEVICE9 pdev;
D3DDISPLAYMODE d3ddm;
D3DPRESENT_PARAMETERS d3dpp;
D3DXMATRIX matWorld,matView,matProj;
LPDIRECT3DVERTEXBUFFER9 pVB;
IDirect3DIndexBuffer9 *pIndexBuffer;
int HEIGHT,WIDTH;
float g_f=0;
ofstream Debug;
#define num 486
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
enum SCREENMODE
{
FULLSCREEN=0,
WINDOWED=1,
};
struct VIEW_MATRIX
{
float x,y,z,ox,oy,oz,ux,uy,uz;
};
struct CUSTOMVERTEX
{
FLOAT x,y,z/*,rhw*/;
DWORD colour;
};
CUSTOMVERTEX g_Vertices[100];
int indices[num];
void SetViewMatrix(VIEW_MATRIX d_vmat)
{
D3DXMatrixLookAtLH(&matView,&D3DXVECTOR3(d_vmat.x,d_vmat.y,d_vmat.z),
&D3DXVECTOR3(d_vmat.ox,d_vmat.oy,d_vmat.oz),
&D3DXVECTOR3(d_vmat.ux,d_vmat.uy,d_vmat.uz));
pdev->SetTransform(D3DTS_VIEW,&matView);
}
void SetWorldMatrix(float min_distance,float max_distance)
{
D3DXMatrixIdentity(&matWorld);
pdev->SetTransform(D3DTS_WORLD,&matWorld);
D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/2,1.0,min_distance,max_distance);
pdev->SetTransform(D3DTS_PROJECTION,&matProj);
}
HRESULT InitGraphics(HWND hwnd,SCREENMODE d_scrm)
{
if(NULL==(pd3d=Direct3DCreate9(D3D_SDK_VERSION)))
return E_FAIL;
if(FAILED(pd3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddm)))
return E_FAIL;
WIDTH=d3ddm.Width;
HEIGHT=d3ddm.Height;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
switch(d_scrm)
{
case FULLSCREEN:
{
d3dpp.Windowed=FALSE;
d3dpp.hDeviceWindow=hwnd;
d3dpp.SwapEffect=D3DSWAPEFFECT_FLIP;
d3dpp.BackBufferCount=2;
d3dpp.BackBufferWidth=800;
d3dpp.BackBufferHeight=600;
d3dpp.FullScreen_RefreshRateInHz=D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval=D3DPRESENT_INTERVAL_IMMEDIATE;
d3dpp.BackBufferFormat=d3ddm.Format;
break;
}
case WINDOWED:
{
d3dpp.Windowed=TRUE;
d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat=D3DFMT_UNKNOWN;
}
}
d3dpp.AutoDepthStencilFormat=D3DFMT_D16;
if(FAILED(pd3d->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hwnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&pdev)))
return E_FAIL;
if(pdev!=NULL)
{
pdev->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);
pdev->SetRenderState(D3DRS_LIGHTING,FALSE);
SetWorldMatrix(0.2f,400.0f);
}
Debug<<"Gra"<<endl;;
return S_OK;
}
void InitWave(CUSTOMVERTEX p[])
{
int iNumberY=10;
int iNumberX=10;
int index;
int temp;
for(int y=0;y<iNumberY;y++)
{
for(int x=0;x<iNumberX;x++)
{
index=y*iNumberX+x;
p[index].x=(x-5)*5;
p[index].y=(y-5)*5;
p[index].z=0;
p[index].colour=D3DCOLOR_XRGB(255*(x%2),255*(y%2),255*((x+y)%2));
if((y!=9)&&(x!=9))
{
temp=(y*9+x)*6;
indices[temp]=index;
indices[temp+1]=index+1;
indices[temp+2]=index+10+1;
indices[temp+3]=index;
indices[temp+4]=index+10+1;
indices[temp+5]=index+10;
}
}
}
}
HRESULT InitGeometry()
{
InitWave(g_Vertices);
if( FAILED( pdev->CreateVertexBuffer( 100*sizeof(CUSTOMVERTEX),
0, D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT, &pVB ,NULL) ) )
{
return E_FAIL;
}
VOID* pVertices;
if( FAILED( pVB->Lock( 0,sizeof(g_Vertices),&pVertices,0 ) ) )
{
return E_FAIL;
}
memcpy( pVertices, g_Vertices, sizeof(g_Vertices) );
pVB->Unlock();
pdev->SetFVF( D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
pdev->SetStreamSource( 0, pVB, sizeof(CUSTOMVERTEX),sizeof(CUSTOMVERTEX));
WORD *pIndex;
if( FAILED(pdev->CreateIndexBuffer( num*sizeof(WORD),
D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16,
D3DPOOL_DEFAULT,
&pIndexBuffer,
NULL)))
{
return E_FAIL;
}
if( FAILED( pIndexBuffer->Lock(0, 0, (VOID **)&pIndex, 0)))
{
return E_FAIL;
};
for(int idx = 0; idx < num; idx++)
pIndex[idx] = indices[idx];
pIndexBuffer->Unlock();
pdev->SetIndices(pIndexBuffer);
Debug<<"Geometry"<<endl;
return S_OK;
}
HRESULT Render()
{
g_f=0.002f+g_f;
VIEW_MATRIX dvm={50*sin(g_f),0.0f,50*cos(g_f),0.0f,0.0f,0.0f,0.0f,1.0f, 0.0f};
SetViewMatrix(dvm);
if(pdev==NULL)
return E_FAIL;
pdev->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0F,0);
pdev->BeginScene();
///
if(FAILED(pdev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
-1,
0,
num,
0,
num/3)))
{
return E_FAIL;
}
pdev->EndScene();
pdev->Present( NULL, NULL, NULL, NULL );
if(pdev->Present(NULL,NULL,NULL,NULL)==D3DERR_DEVICELOST)
if(pdev->TestCooperativeLevel()==D3DERR_DEVICENOTRESET)
{
pVB->Release();
if(FAILED(pdev->Reset(&d3dpp)))
return E_FAIL;
InitGeometry();
pdev->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
pdev->SetRenderState(D3DRS_LIGHTING,FALSE);
SetWorldMatrix(0.2f,400.0f);
};
return S_OK;
}
LRESULT WINAPI MsgProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_DESTROY:
PostQuitMessage( 0 );
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam );
}
//Main
INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, INT)
{
int t=0;
Debug.open("Debug.txt");
Debug<<"start"<<endl;
g_f=-20;
WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
"D3D", NULL };
RegisterClassEx( &wc );
HWND hwnd = CreateWindow( "D3D", "3D",
WS_OVERLAPPEDWINDOW, 100, 100, 500, 500,
GetDesktopWindow(), NULL, wc.hInstance, NULL );
if(SUCCEEDED(InitGraphics(hwnd,FULLSCREEN)))
{
if(SUCCEEDED(InitGeometry()))
{
Debug<<"0";
ShowWindow( hwnd, SW_SHOWDEFAULT );
UpdateWindow(hwnd );
MSG msg;
ZeroMemory( &msg, sizeof(msg) );
for(;;)
{
Debug<<t++;
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
if(msg.message==WM_QUIT)
{
if(pVB!=NULL)
pIndexBuffer->Release();
else Debug<<"Err";
if(pVB!=NULL)
pVB->Release();
else Debug<<"Err";
pdev->Release();
pd3d->Release();
break;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
if(FAILED(Render()))break;
}
}
}
return S_OK;
}