⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 3dtut.cpp

📁 COM Component designed to make full screen scrolling maps easy, especially from Visual Basic. This i
💻 CPP
字号:
//This is a fully functional DX app that draws a triangle in fullscreen mode and rotates it (like the triangle sample in the SDK)
//e-mail me at wulf@ignmail.com for suggestions/requests/criticizims (no flames please, i'll just block you)
//Code Copyright (c) 2000, by Albert Chaulk

//Stuff: add winmm.lib ddraw.lib d3dim.lib d3dframe.lib & dxguid.lib to the project's link (and add/change directories
//to search, etc) If you still get errors, try adding #define INITGUID. If that doesn't work, add every lib in the SDK lib dir

#define D3D_OVERLOADS

#include <windows.h>
#include <mmsystem.h>
#include <ddraw.h>
#include <d3d.h>
#include <d3dtypes.h>
#include "d3dutil.h"
#include "d3dmath.h"//probably not needed for this
#include "d3dtextr.h"//probably not needed

LPDIRECT3D7 lp_D3D=NULL;
LPDIRECTDRAW7 lp_DD=NULL;

LPDIRECT3DDEVICE7 lpDevice=NULL;
LPDIRECTDRAWSURFACE7 lpPrimary=NULL;
LPDIRECTDRAWSURFACE7 lpBack=NULL;
LPDIRECTDRAWSURFACE7 lpZBuf=NULL;

#define Release(x) if(x){ x->Release(); /*delete x;*/ x=NULL; };
#define Delete(x) if(x){ /*x->Release();*/ delete x; x=NULL; };
#define ReleaseDelete(x) if(x){ x->Release(); delete x; x=NULL; };

struct ScreenProp{
	UINT x;
	UINT y;
	UINT bpp;

	ScreenProp::ScreenProp() { x=640; y=480; bpp=8; };//640x480x8 is universal
	ScreenProp::ScreenProp(UINT nx,UINT ny,UINT nbpp) { x=nx; y=ny; bpp=nbpp; };
};

HWND m_hWnd;

BOOL InitGlobal(HRESULT &hr,ScreenProp scr);

void Render(LPDIRECTDRAWSURFACE7 lpSurf,LPDIRECTDRAWSURFACE7,LPDIRECT3DDEVICE7 lpDev,float elapsed,float);
LRESULT CALLBACK WindowProc(HWND hWnd,unsigned uMsg,WPARAM wParam,LPARAM lParam);
void Cleanup();

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmd,int Show)
{
	DWORD current_time;
	DWORD last_time;
	float time_elapsed;
	float time_scale;

	time_scale=0.001f;//constant 1ms in win95

const char class_name[]="Tutorial";
const char app_name[]="Albert Chaulk's Tutorial";


	WNDCLASS wc;
	wc.style=CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc=(WNDPROC)WindowProc;
	wc.cbClsExtra=0;
	wc.cbWndExtra=sizeof(DWORD);
	wc.hInstance=hInst;
	wc.hIcon=NULL;
	wc.hCursor=LoadCursor(NULL,IDC_ARROW);
	wc.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
	wc.lpszMenuName=NULL;
	wc.lpszClassName=class_name;

	if(!RegisterClass(&wc))
        return 0;

	m_hWnd=CreateWindow(class_name,app_name,WS_VISIBLE|WS_POPUP,0,0,GetSystemMetrics(SM_CXSCREEN)
		,GetSystemMetrics(SM_CYSCREEN),NULL,NULL,hInst,NULL);
	if(!m_hWnd)
		return 0;

	ShowWindow(m_hWnd,SW_SHOW);
	UpdateWindow(m_hWnd);

	HRESULT hr;

	InitGlobal(hr,ScreenProp(640,480,16));


    BOOL bGotMsg;
    MSG  msg;
    PeekMessage(&msg,NULL,0,0,PM_NOREMOVE);
	
    while(msg.message!=WM_QUIT)
	{
		bGotMsg=PeekMessage(&msg,NULL,0,0,PM_REMOVE);
		if(bGotMsg)
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else{
			current_time=timeGetTime(); 

			time_elapsed=(current_time-last_time)*time_scale;
			
			last_time=current_time;

			Render(lpPrimary,lpBack,lpDevice,time_elapsed,current_time*time_scale);
		}
    }

	// return final message
    return msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hWnd,unsigned uMsg,WPARAM wParam,LPARAM lParam)
{
	switch(uMsg){
	case WM_KEYDOWN:
		switch(wParam){
		case VK_ESCAPE:
			DestroyWindow(hWnd);
			break;

		}
		break;

	case WM_DESTROY:
		Cleanup();
		PostQuitMessage(0);
		break;
	}

	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

void Render(LPDIRECTDRAWSURFACE7 lpSurf,LPDIRECTDRAWSURFACE7 lpBackBuf,LPDIRECT3DDEVICE7 lpDev,float elapsed,float total)
{

	D3DMATRIX mat;
	D3DVERTEX g_pvTriangleVertices[6];


	D3DVECTOR p1( 0.0f, 3.0f, 0.0f );
	D3DVECTOR p2( 3.0f,-3.0f, 0.0f );
	D3DVECTOR p3(-3.0f,-3.0f, 0.0f );
	D3DVECTOR vNormal( 0.0f, 0.0f, 1.0f );
	
	// Initialize the 3 vertices for the front of the triangle
	g_pvTriangleVertices[0] = D3DVERTEX( p1, vNormal, 0.0f, 0.0f );
	g_pvTriangleVertices[1] = D3DVERTEX( p2, vNormal, 0.0f, 0.0f );
	g_pvTriangleVertices[2] = D3DVERTEX( p3, vNormal, 0.0f, 0.0f );
    
	// Initialize the 3 vertices for the back of the triangle
	g_pvTriangleVertices[3] = D3DVERTEX( p1, -vNormal, 0.0f, 0.0f );
	g_pvTriangleVertices[4] = D3DVERTEX( p3, -vNormal, 0.0f, 0.0f );
	g_pvTriangleVertices[5] = D3DVERTEX( p2, -vNormal, 0.0f, 0.0f );

    D3DMATERIAL7 mtrl;
    ZeroMemory( &mtrl, sizeof(mtrl) );
    mtrl.ambient.r = 1.0f;
    mtrl.ambient.g = 1.0f;
    mtrl.ambient.b = 0.0f;

	if(FAILED(lpDev->BeginScene()))
		return;
	
	D3DUtil_SetViewMatrix(mat,D3DVECTOR(0.0f,0.0f,-15.0f),D3DVECTOR(0.0f,0.0f,1.0f),D3DVECTOR(0.0f,1.0f,0.0f));
	lpDev->SetTransform(D3DTRANSFORMSTATE_VIEW,&mat);

	D3DUtil_SetRotateYMatrix(mat,total);
	lpDev->SetTransform(D3DTRANSFORMSTATE_WORLD,&mat);

    lpDev->SetMaterial( &mtrl );
    lpDev->SetRenderState( D3DRENDERSTATE_AMBIENT, 0xffffffff );
	lpDev->Clear(0,NULL,D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET,0,1.0f,0);

    lpDev->DrawPrimitive( D3DPT_TRIANGLELIST, D3DFVF_VERTEX,g_pvTriangleVertices, 6, NULL );

	lpDev->EndScene();

	lpSurf->Flip(lpBackBuf,0);
}

void Cleanup()
{
	Release(lpDevice);
	Release(lp_D3D);

	Release(lpZBuf);
	Release(lpBack);
	Release(lpPrimary);
	Release(lp_DD);
}

BOOL InitInterfaces(HRESULT& hr)
{
	if(FAILED(hr=DirectDrawCreateEx(NULL,(VOID**)&lp_DD,IID_IDirectDraw7,NULL)))
		return FALSE;

	if(FAILED(hr=lp_DD->QueryInterface(IID_IDirect3D7,(VOID**)&lp_D3D)))
		return FALSE;

	return TRUE;
}

BOOL InitDDraw(HRESULT& hr,UINT x,UINT y,UINT bpp)
{
	//set coop to exclusive, fullscreen mode. DDSCL_FPUSETUP is optional
	if(FAILED(hr=lp_DD->SetCooperativeLevel(m_hWnd,DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN)))
		return FALSE;

	//set to x by y by bpp screen mode
	if(FAILED(hr=lp_DD->SetDisplayMode(x,y,bpp,0,0)))
		return FALSE;

	//create primary surf, attach backbuffer
    DDSURFACEDESC2 ddsd;
	ZeroMemory(&ddsd,sizeof(ddsd));
    ddsd.dwSize=sizeof(ddsd);
    ddsd.dwFlags=DDSD_CAPS|DDSD_BACKBUFFERCOUNT;
    ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP|DDSCAPS_3DDEVICE|DDSCAPS_COMPLEX;
    ddsd.dwBackBufferCount=1;
    if(FAILED(hr=lp_DD->CreateSurface(&ddsd,&lpPrimary,NULL)))
		return FALSE;

	//get the backbuffer
	DDSCAPS2 ddscaps;
	ZeroMemory(&ddscaps,sizeof(ddscaps));
	ddscaps.dwCaps=DDSCAPS_BACKBUFFER;
	if(FAILED(hr=lpPrimary->GetAttachedSurface(&ddscaps,&lpBack)))
		return FALSE;

	return TRUE;
}

BOOL use_ZBuffer;

static HRESULT WINAPI EnumZBufferFormatsCallback(DDPIXELFORMAT *pddpf,VOID *pddpfDesired)
{
    // if parameters==NULL, don't enumerate more

	use_ZBuffer=FALSE;

	if(pddpf==NULL||pddpfDesired==NULL)
        return D3DENUMRET_CANCEL;

    // if the current pixel format's match the desired ones (DDPF_ZBUFFER and
    // possibly DDPF_STENCILBUFFER),lets copy it and return. This function is
    // not choosy... it accepts the first valid format that comes along.
	if(pddpf->dwFlags==((DDPIXELFORMAT*)pddpfDesired)->dwFlags)
	{
		memcpy(pddpfDesired,pddpf,sizeof(DDPIXELFORMAT));

		use_ZBuffer=TRUE;
		
		return D3DENUMRET_CANCEL;
	}

	return D3DENUMRET_OK;
}

BOOL InitD3D(HRESULT& hr,UINT x,UINT y)
{
	DDPIXELFORMAT m_ddpfZBuffer;
	ZeroMemory(&m_ddpfZBuffer,sizeof(m_ddpfZBuffer));
	m_ddpfZBuffer.dwSize=sizeof(m_ddpfZBuffer);
	m_ddpfZBuffer.dwFlags=DDPF_ZBUFFER;

	int zbuf_format;
	//get best format, from hardware to software
	lp_D3D->EnumZBufferFormats(IID_IDirect3DTnLHalDevice,EnumZBufferFormatsCallback,(VOID*)&m_ddpfZBuffer);
	if(use_ZBuffer){
		zbuf_format=1;
	}
	else{
		lp_D3D->EnumZBufferFormats(IID_IDirect3DHALDevice,EnumZBufferFormatsCallback,(VOID*)&m_ddpfZBuffer);
		if(use_ZBuffer){
			zbuf_format=2;
		}
		else{
			lp_D3D->EnumZBufferFormats(IID_IDirect3DMMXDevice,EnumZBufferFormatsCallback,(VOID*)&m_ddpfZBuffer);
			if(use_ZBuffer){
				zbuf_format=3;
			}
			else{
				lp_D3D->EnumZBufferFormats(IID_IDirect3DRGBDevice,EnumZBufferFormatsCallback,(VOID*)&m_ddpfZBuffer);
				if(use_ZBuffer)
					zbuf_format=4;
			}
		}
	}

	DDSURFACEDESC2 ddsd;
	ZeroMemory(&ddsd,sizeof(ddsd));
    ddsd.dwSize=sizeof(ddsd);
    ddsd.dwFlags=DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;

	if(use_ZBuffer){
		if(zbuf_format<3)
			ddsd.ddsCaps.dwCaps=DDSCAPS_ZBUFFER|DDSCAPS_VIDEOMEMORY;
		else
			ddsd.ddsCaps.dwCaps=DDSCAPS_ZBUFFER|DDSCAPS_SYSTEMMEMORY;
	
		//set to res
		ddsd.dwWidth=x;
		ddsd.dwHeight=y;
		ddsd.ddpfPixelFormat.dwSize=sizeof(DDPIXELFORMAT);
		ddsd.ddpfPixelFormat.dwFlags=DDPF_ZBUFFER;
		memcpy(&ddsd.ddpfPixelFormat,&m_ddpfZBuffer,sizeof(DDPIXELFORMAT));
		if(FAILED(hr=lp_DD->CreateSurface(&ddsd,&lpZBuf,NULL)))
			return FALSE;;

		lpBack->AddAttachedSurface(lpZBuf);//add zbuf to surface
	}

	//get best device, from full t&l to software
	if((hr=lp_D3D->CreateDevice(IID_IDirect3DTnLHalDevice,lpBack,&lpDevice))!=D3D_OK)
		if((hr=lp_D3D->CreateDevice(IID_IDirect3DHALDevice,lpBack,&lpDevice))!=D3D_OK)
			if((hr=lp_D3D->CreateDevice(IID_IDirect3DMMXDevice,lpBack,&lpDevice))!=D3D_OK)
				if((hr=lp_D3D->CreateDevice(IID_IDirect3DRGBDevice,lpBack,&lpDevice))!=D3D_OK)
					return FALSE;

	//setup viewport
	D3DVIEWPORT7 view;
	view.dwX=0;
	view.dwY=0;
	view.dwWidth=x;
	view.dwHeight=y; 
	view.dvMinZ=0.0f;
	view.dvMaxZ=1.0f;
	if(lpDevice->SetViewport(&view)!=D3D_OK)
		return FALSE;

	D3DMATRIX proj;
	
	//Set projection matrix. 
	D3DUtil_SetProjectionMatrix(proj,0.8f,(float)((float)x/(float)y)/*1.333 is standard*/,10.0f,2000.0f/*min/max clipping*/);
	lpDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION,&proj);

	//linear tex filtering
	lpDevice->SetTextureStageState(0,D3DTSS_MAGFILTER,D3DTFG_LINEAR|D3DTFG_ANISOTROPIC);

	//Enable z-buffering. 
    lpDevice->SetRenderState(D3DRENDERSTATE_ZENABLE,TRUE);

	//Set ambient light color
	lpDevice->SetRenderState(D3DRENDERSTATE_AMBIENT,D3DRGBA(0.1f,0.1f,0.1f,0.1f));

	return TRUE;
}

BOOL InitGlobal(HRESULT &hr,ScreenProp scr)
{
	if(!InitInterfaces(hr))
		return FALSE;

	if(!InitDDraw(hr,scr.x,scr.y,scr.bpp))
		return FALSE;

	if(!InitD3D(hr,scr.x,scr.y))
		return FALSE;

	return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -