Direct3D 简介


  首先 Direct3DCreate9 创建IDirect3D9 对象,这个方法是对Com 创建对象封装,封装套间初始化,类厂创建,IDirect3D9 对象创建为一体。所以使用了这个API,那么就直接Ok。

然后在创建LPDIRECT3DDEVICE9 对象,IDirect3D9 的CreateDevice来创建。

有了这个对象之后,就可以画图了,当然必须在g_pD3DDevice->BeginScene(); 和 g_pD3DDevice->EndScene(); 之间,因为这样相当于Gdi中的BeginPaitDC ,就是准备,同样,EndScene 表示画完毕了,

最后,将画好的图片贴出去g_pD3DDevice->Present(NULL, NULL, NULL, NULL);


1. 我们看看如何获得IDirect3D9 对象和设备对象

HRESULT Init3D(HWND hWnd)
{
	if ( NULL == g_pD3D )
	{
		g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
	}

	if (NULL == g_pD3D )
	{
		return E_FAIL;
	}


	D3DDISPLAYMODE d3ddm;

	FillMemory(&d3ddm, sizeof(D3DDISPLAYMODE), 0);

	if (FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)))
	{
		return E_FAIL;
	}

	D3DPRESENT_PARAMETERS d3dpm;
	FillMemory(&d3dpm, sizeof(D3DPRESENT_PARAMETERS), 0);
	d3dpm.Windowed         = TRUE;
	d3dpm.SwapEffect       = D3DSWAPEFFECT_DISCARD;
	d3dpm.BackBufferFormat = d3ddm.Format;

	if (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
		D3DDEVTYPE_HAL,
		hWnd,
		D3DCREATE_SOFTWARE_VERTEXPROCESSING,
		&d3dpm,
		&g_pD3DDevice)))

	{
		return E_FAIL;
	}

	if ( NULL == g_pD3DDevice )

	{
		return E_FAIL;
	}

	return S_OK;
}

那么画图部分

void Render()
{
#define D3DFVF_MYVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)

	g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255, 128, 0), 1.0f, 0);

	g_pD3DDevice->BeginScene();

	// draw here

	g_pD3DDevice->SetStreamSource(0, g_pD3DVBuffer, 0, sizeof(DrawVertex)); 

	g_pD3DDevice->SetFVF(D3DFVF_MYVERTEX);                               

	g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0,  1);  

	g_pD3DDevice->EndScene();

	g_pD3DDevice->Present(NULL, NULL, NULL, NULL);

}




我将整个工程的代码贴在下面

// direct3d1.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "direct3d1.h"
#include <d3d9.h>
//#include <D3dx9core.h>
//#include <d3d10.h>
#pragma comment(lib, "D3D9.lib")
//#pragma comment(lib,"D3dx9.lib")


#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;								// current instance
TCHAR szTitle[MAX_LOADSTRING];					// The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];			// the main window class name

LPDIRECT3D9             g_pD3D        = NULL;
LPDIRECT3DDEVICE9       g_pD3DDevice  = NULL;
IDirect3DVertexBuffer9*  g_pD3DVBuffer = NULL;







// Forward declarations of functions included in this code module:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);




HRESULT Init3D(HWND hWnd);
void    Render( void );
void    Term3D( void );
INT     DoMSGLoop( void );
HRESULT InitVertexBuffer();


int APIENTRY _tWinMain(HINSTANCE hInstance,
					   HINSTANCE hPrevInstance,
					   LPTSTR    lpCmdLine,
					   int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

	// TODO: Place code here.
	//MSG msg;
	HACCEL hAccelTable;
	INT ExitCode = 0;

	// Initialize global strings
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_DIRECT3D1, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_DIRECT3D1));

	// Main message loop:
// 	while (GetMessage(&msg, NULL, 0, 0))
// 	{
// 		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
// 		{
// 			TranslateMessage(&msg);
// 			DispatchMessage(&msg);
// 		}
// 	}

	ExitCode = DoMSGLoop();

	Term3D();

	return ExitCode;
}



//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
//    This function and its usage are only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_DIRECT3D1));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_DIRECT3D1);
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	return RegisterClassEx(&wcex);
}

//
//   FUNCTION: InitInstance(HINSTANCE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
	HWND hWnd;

	hInst = hInstance; // Store instance handle in our global variable

	hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

	if (!hWnd)
	{
		return FALSE;
	}

	if (FAILED(Init3D(hWnd)))
	{
		DestroyWindow(hWnd);
		return FALSE;
	}

	InitVertexBuffer();

	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	return TRUE;
}

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND	- process the application menu
//  WM_PAINT	- Paint the main window
//  WM_DESTROY	- post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;

	switch (message)
	{
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// Parse the menu selections:
		switch (wmId)
		{
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
// 	case WM_PAINT:
// 		hdc = BeginPaint(hWnd, &ps);
// 		// TODO: Add any drawing code here...
// 		EndPaint(hWnd, &ps);
// 		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(lParam);
	switch (message)
	{
	case WM_INITDIALOG:
		return (INT_PTR)TRUE;

	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
		{
			EndDialog(hDlg, LOWORD(wParam));
			return (INT_PTR)TRUE;
		}
		break;
	}
	return (INT_PTR)FALSE;
}

HRESULT Init3D(HWND hWnd)
{
	if ( NULL == g_pD3D )
	{
		g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
	}

	if (NULL == g_pD3D )
	{
		return E_FAIL;
	}


	D3DDISPLAYMODE d3ddm;

	FillMemory(&d3ddm, sizeof(D3DDISPLAYMODE), 0);

	if (FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)))
	{
		return E_FAIL;
	}

	D3DPRESENT_PARAMETERS d3dpm;
	FillMemory(&d3dpm, sizeof(D3DPRESENT_PARAMETERS), 0);
	d3dpm.Windowed         = TRUE;
	d3dpm.SwapEffect       = D3DSWAPEFFECT_DISCARD;
	d3dpm.BackBufferFormat = d3ddm.Format;

	if (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
		D3DDEVTYPE_HAL,
		hWnd,
		D3DCREATE_SOFTWARE_VERTEXPROCESSING,
		&d3dpm,
		&g_pD3DDevice)))

	{
		return E_FAIL;
	}

	if ( NULL == g_pD3DDevice )

	{
		return E_FAIL;
	}

	return S_OK;
}

INT DoMSGLoop()
{
	BOOL bMsg = FALSE;
	MSG  msg;
	PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
	while (msg.message != WM_QUIT)
	{

		bMsg = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);

		if (bMsg)
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			Render();
		}
	}

	return (INT)msg.wParam;
}

struct DrawVertex
{
	FLOAT x, y, z, rhw;
	DWORD colour;
};

void Render()
{
#define D3DFVF_MYVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)

	g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255, 128, 0), 1.0f, 0);

	g_pD3DDevice->BeginScene();

	// draw here

	g_pD3DDevice->SetStreamSource(0, g_pD3DVBuffer, 0, sizeof(DrawVertex)); 

	g_pD3DDevice->SetFVF(D3DFVF_MYVERTEX);                               

	g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0,  1);  

	g_pD3DDevice->EndScene();

	g_pD3DDevice->Present(NULL, NULL, NULL, NULL);

}



void Term3D()
{
	if (g_pD3DDevice != NULL)
	{
		g_pD3DDevice->Release();
		g_pD3DDevice = NULL;
	}

	if (g_pD3D != NULL)
	{
		g_pD3D->Release();
		g_pD3D = NULL;
	}

}



HRESULT InitVertexBuffer()
{
	#define D3DFVF_MYVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)

	LPVOID pV = NULL;

	DrawVertex aVertex[] =
	{
		{450.0f, 100.0f, 0.0f, 0.0f, D3DCOLOR_XRGB(0, 0, 255) },

		{600.0f, 300.0f, 0.0f, 0.0f, D3DCOLOR_XRGB(0, 255, 0) },

		{300.0f, 300.0f, 0.0f, 0.0f, D3DCOLOR_XRGB(255, 0, 0) }
	};



	UINT nSize = 3 * sizeof(DrawVertex);

	if(FAILED(g_pD3DDevice->CreateVertexBuffer(nSize,

		D3DUSAGE_SOFTWAREPROCESSING,

		D3DFVF_MYVERTEX,

		D3DPOOL_DEFAULT,

		&g_pD3DVBuffer,

		NULL)))

	{
		return E_FAIL;
	}

	if(FAILED(g_pD3DVBuffer->Lock(0, nSize, &pV, 0)))
	{
		return E_FAIL;
	}

	MoveMemory(pV, aVertex, nSize);

	g_pD3DVBuffer->Unlock();

	return S_OK;
}




效果图如下:



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值