[DirectX]はじめての3Dゲーム:Chapter1-Chapter2

       最近找到了一个比较好玩的东西,日本DirectX的教材,有很多本,最简单的最符合新手的「ゲームプログラミング入門 第2版」(游戏编程入门 第2版),没有找到资源,倒是找到了也算是DirectX的新手教材「はじめての3Dゲーム」(第一个3D游戏),那就有意思了,因为据说日本人的代码风格应该算是很严谨规范的,看看好不好玩。(这篇文章是我刚下到资源后看了会写的,过去快2个月了,共192页的PDF也看到175多页了,其实相当于看完了,后面全是讲通信对战什么的,没有代码,没有案例。给我的印象也就是日本人也不是很严谨呀。)

PDF加源码:下载地址

       书比较老,估计会跟《Programming.Role.Playing.Games》一样,有些代码估计都不能用,先看看再说。第1章千篇一律都是DirectX的环境搭建,而且还是VC6++的版本搭建,这个就不多说了。题外话,书本作者说是为了让新手快速入门,所以有些地方讲错就不要在意,还有就是要多会使用复制和粘贴代码功能。我这边也说一句,我不会去翻译书本,第一费时间,第二语文功底太差(曾经做过游戏汉化,被人吐槽过)。

       第2章就有意思了,用DirectX在应用程序中显示一个坦克的图片,不像其他书本,一开始只介绍Window初始化,或者DirectX初始化,这些其实一开始还是比较繁琐的枯燥的工作,而且还是比较难理解的,有些人死脑筋就会卡在这很久然后就放弃,我还真见到过几个这样的人。

       其实只要记住Window初始化就这么几步,注册窗口类(RegisterClassEx),创建窗口对象(CreateWindowEx),显示窗口(ShowWindow),消息循环。消息循环中注意游戏开发不要用GetMessage方法,要用PeekMessage方法,是因为GetMessage方法是阻塞函数。

       其实DX9的初始化相对于DX10/11来说,简直不要太简单,就这么几步:创建一个IDirect3D9指针对象,再根据IDirect3D9指针对象创建IDirect3DDevice9指针对象,初始化就完成了。

       书本源码:

#include <windows.h>
#include <d3dx9.h>

LPDIRECT3D9 pD3d;
LPDIRECT3DDEVICE9 pDevice; 
LPDIRECT3DTEXTURE9 pTexture;
LPD3DXSPRITE pSprite;

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HRESULT InitD3d(HWND);
VOID DrawSprite();

//
//INT WINAPI WinMain( HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR szStr,INT iCmdShow)
//アプリケーションのエントリー関数
// 程序的入口函数
INT WINAPI WinMain( HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR szStr,INT iCmdShow)
{
	HWND hWnd=NULL;
	MSG msg;
	// ウィンドウの初期化
	// Window的初始化
	static char szAppName[] = "Chapter2" ;     
     WNDCLASSEX  wndclass ;

     wndclass.cbSize           = sizeof (wndclass) ;
     wndclass.style              = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc    = WndProc ;
     wndclass.cbClsExtra      = 0 ;
     wndclass.cbWndExtra     = 0 ;
     wndclass.hInstance        = hInst ;
     wndclass.hIcon             = LoadIcon (NULL, IDI_APPLICATION) ;
     wndclass.hCursor          = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH) ;
     wndclass.lpszMenuName = NULL ;
     wndclass.lpszClassName = szAppName ;
     wndclass.hIconSm         = LoadIcon (NULL, IDI_APPLICATION) ;

     RegisterClassEx (&wndclass) ;

     hWnd = CreateWindow (szAppName,szAppName,WS_OVERLAPPEDWINDOW,   
                    0,0,640,480,NULL,NULL,hInst,NULL) ;	  
    ShowWindow (hWnd,SW_SHOW) ;
    UpdateWindow (hWnd) ;
	// ダイレクト3Dの初期化関数を呼ぶ
	// 调用Direct3D初始化函数
	if(FAILED(InitD3d(hWnd)))
	{
		return 0;
	}
	// メッセージループ
	// 消息循环
    ZeroMemory( &msg, sizeof(msg) );
    while( msg.message!=WM_QUIT )
     {
		 if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
         {
			 TranslateMessage( &msg );
             DispatchMessage( &msg );
         }
         else
		 {
			 DrawSprite();
		 }                    
	 }
     return (INT)msg.wParam ;
}

//
//LRESULT CALLBACK WndProc(HWND hWnd,UINT iMsg,WPARAM wParam,LPARAM lParam)
// ウィンドウプロシージャ関数
// 窗口回调函数,用于处理消息
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMsg,WPARAM wParam,LPARAM lParam)
{	
	switch(iMsg)
	{
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		case WM_KEYDOWN:
		switch((CHAR)wParam)
		{
			case VK_ESCAPE:
				PostQuitMessage(0);
				break;
		}
		break;
	}
	return DefWindowProc (hWnd, iMsg, wParam, lParam) ;	
}

//
//HRESULT InitD3d(HWND hWnd)
//ダイレクト3Dの初期化関数
// Direct3D初始化函数
HRESULT InitD3d(HWND hWnd)
{
	// 「Direct3D」オブジェクトの作成
	// 创建Direct3D对象
	if( NULL == ( pD3d = Direct3DCreate9( D3D_SDK_VERSION ) ) )
	{
		MessageBox(0,"Direct3Dの作成に失敗しました","",MB_OK);
        return E_FAIL;
	}
	// 「DIRECT3Dデバイス」オブジェクトの作成
	// 创建Direct3D设备对象
	D3DPRESENT_PARAMETERS d3dpp; 
	ZeroMemory( &d3dpp, sizeof(d3dpp) );
   
	d3dpp.BackBufferFormat =D3DFMT_UNKNOWN;
	d3dpp.BackBufferCount=1;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;	
	d3dpp.Windowed = TRUE;
	
	 if( FAILED( pD3d->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                      D3DCREATE_MIXED_VERTEXPROCESSING,
                                      &d3dpp, &pDevice ) ) )
    {
		MessageBox(0,"HALモードでDIRECT3Dデバイスを作成できません\nREFモードで再試行します",NULL,MB_OK);
		if( FAILED( pD3d->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd,
                                      D3DCREATE_MIXED_VERTEXPROCESSING,
                                      &d3dpp, &pDevice ) ) )
		{
			MessageBox(0,"DIRECT3Dデバイスの作成に失敗しました",NULL,MB_OK);
			 return E_FAIL;
		}   
    } 
	//「テクスチャオブジェクト」の作成
	// 创建texture
	if(FAILED(D3DXCreateTextureFromFileEx(pDevice,"Sprite.bmp",100,100,0,0,	D3DFMT_UNKNOWN,
											D3DPOOL_DEFAULT,D3DX_FILTER_NONE,D3DX_DEFAULT,
								            0xff000000,NULL,NULL,&pTexture)))
	{
		MessageBox(0,"テクスチャの作成に失敗しました","",MB_OK);
		return E_FAIL;
	} 
	// 「スプライトオブジェクト」の作成
	// 创建sprite
	if(FAILED(D3DXCreateSprite(pDevice,&pSprite)))
	{
		MessageBox(0,"スプライトの作成に失敗しました","",MB_OK);
		return E_FAIL;
	}
	return S_OK;
}

//
//VOID DrawSprite()
//スプライトを描画する関数
// 绘制Sprite函数
VOID DrawSprite()
{
	pDevice->Clear( 0, NULL, D3DCLEAR_TARGET,D3DCOLOR_XRGB(100,100,100), 1.0f, 0 );
	if( SUCCEEDED( pDevice->BeginScene() ) )
	{
		RECT rect={0,0,100,100};
		D3DXVECTOR2 vec2Scale(1.0,1.0);
		D3DXVECTOR2 vec2RotationCenter(1.0,1.0);
		D3DXVECTOR2 vec2Position(270,180);	
		pSprite->Draw(pTexture,&rect,&vec2Scale,&vec2RotationCenter,0,&vec2Position,0xffffffff);
		pDevice->EndScene();
	}	
	pDevice->Present( NULL, NULL, NULL, NULL );	
}

       自己修改了下一些老旧的API,主要是DrawSprite函数中的接口,可以编译运行,运行环境是DX9加VS2017。ID3DXSprite这个之前没怎么用过,也就搜了一下,了解了一下,具体的可以百度和Google一下。PS:最近在看另外一本书,书上说BeginScene和EndScene这两个方法是用在3D上渲染的,也就是底层调用DrawPrimitive函数绘制图元才需要的,也就是点,线和三角面。自己测了一下,好像是这样的,这个案例我也测过,必须要有BeginScene和EndScene这两个方法,也就是说ID3DXSprite底层应该也是用DrawPrimitive函数绘制图元来实现的,正不正确就不清楚了。

       自己修改后的代码:

#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
#pragma comment(lib, "legacy_stdio_definitions.lib")
#pragma comment(lib, "DxErr.lib")

#define WIN32_LEAN_AND_MEAN
#define SAFE_RELEASE(p) { if(p) { p->Release(); p = nullptr; } }

#include <Windows.h>
#include <d3dx9.h>
#include <DxErr.h>

#define DEFAULT_WINDOW_TITLE TEXT("DirectX_09_Chapter02")
#define DEFAULT_SCREEN_WIDTH 640
#define DEFAULT_SCREEN_HEIGHT 480

IDirect3D9* d3d9;
IDirect3DDevice9* device;
ID3DXSprite* sprite;
IDirect3DTexture9* texture;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
HRESULT InitD3D(HWND hwnd);
HRESULT InitSprite();
void Render();
void RenderSprite();
void Release();

int WINAPI WinMain(HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPSTR lpCmdLine,
	int nCmdShow)
{
	WNDCLASSEX wc;
	wc.cbClsExtra = 0;
	wc.cbSize = sizeof(wc);
	wc.cbWndExtra = 0;
	wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wc.hIconSm = wc.hIcon;
	wc.hInstance = hInstance;
	wc.lpfnWndProc = WndProc;
	wc.lpszClassName = DEFAULT_WINDOW_TITLE;
	wc.lpszMenuName = nullptr;
	wc.style = CS_HREDRAW | CS_VREDRAW;

	if (!RegisterClassEx(&wc))
	{
		MessageBox(NULL, TEXT("RegisterClassEx function failed"), TEXT("Error"), MB_OK | MB_ICONERROR);
		return 0;
	}

	auto hwnd = CreateWindowEx(WS_EX_APPWINDOW,
		wc.lpszClassName,
		wc.lpszClassName,
		WS_OVERLAPPEDWINDOW,
		0, 0,
		DEFAULT_SCREEN_WIDTH, DEFAULT_SCREEN_HEIGHT,
		NULL,
		NULL,
		hInstance,
		nullptr);
	if (!hwnd)
	{
		MessageBox(NULL, TEXT("CreateWindowEx function failed"), TEXT("Error"), MB_OK | MB_ICONERROR);
		return 0;
	}

	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);

	auto result = InitD3D(hwnd);
	if (FAILED(result))
		return 0;

	MSG msg;
	memset(&msg, 0, sizeof(msg));

	while (msg.message != WM_QUIT)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}

		Render();
	}

	Release();

	return (int)msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_KEYDOWN:
		{
			switch ((char)wParam)
			{
			case VK_ESCAPE:
				PostQuitMessage(0);
				break;
			}
		}
		break;
	}

	return DefWindowProc(hwnd, msg, wParam, lParam);
}

HRESULT InitD3D(HWND hwnd)
{
	d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
	if (!d3d9)
	{
		MessageBox(NULL, TEXT("Direct3DCreate9 function failed"), TEXT("Error"), MB_OK | MB_ICONERROR);
		return E_FAIL;
	}

	D3DPRESENT_PARAMETERS d3dpp;
	memset(&d3dpp, 0, sizeof(d3dpp));
	d3dpp.BackBufferCount = 1;
	d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.Windowed = true;

	auto result = d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &device);
	if (FAILED(result))
	{
		DXTRACE_ERR_MSGBOX(TEXT("The HAL mode of Direct3D device create failed,\ntry to create the REF mode"), result);
		result = d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hwnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &device);
		if (FAILED(result))
		{
			DXTRACE_ERR_MSGBOX(TEXT("Direct3D device create failed"), result);
			return E_FAIL;
		}
	}

	result = InitSprite();
	if (FAILED(result))
		return E_FAIL;

	return S_OK;
}

HRESULT InitSprite()
{
	auto result = D3DXCreateSprite(device, &sprite);
	if (FAILED(result))
	{
		DXTRACE_ERR_MSGBOX(TEXT("D3DXCreateSprite function failed"), result);
		return E_FAIL;
	}

	result = D3DXCreateTextureFromFileEx(device, TEXT("Sprite.bmp"), 100, 100, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
		D3DX_FILTER_NONE, D3DX_DEFAULT, 0xff000000, nullptr, nullptr, &texture);
	if (FAILED(result))
	{
		DXTRACE_ERR_MSGBOX(TEXT("D3DXCreateTextureFromFileEx function failed"), result);
		return E_FAIL;
	}

	return S_OK;
}

void Render()
{
	auto color = D3DCOLOR_COLORVALUE(0.5f, 0.5f, 0.5f, 1.0f);
	device->Clear(0, nullptr, D3DCLEAR_TARGET, color, 1.0f, 0);
	device->BeginScene();

	RenderSprite();

	device->EndScene();
	device->Present(nullptr, nullptr, NULL, nullptr);
}

void RenderSprite()
{
	sprite->Begin(D3DXSPRITE_ALPHABLEND);
	RECT rect = { 0, 0, 100, 100 };
	D3DXVECTOR3 center(0.0f, 0.0f, 0.0f);
	D3DXVECTOR3 position(270.0f, 180.0f, 0.0f);
	auto color = D3DCOLOR_COLORVALUE(1.0f, 1.0f, 1.0f, 1.0f);
	sprite->Draw(texture, &rect, &center, &position, color);
	sprite->End();
}

void Release()
{
	SAFE_RELEASE(texture);
	SAFE_RELEASE(sprite);
	SAFE_RELEASE(device);
	SAFE_RELEASE(d3d9);
}

源码下载:下载地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【视频教程】Hands-on Three.js 3D Web Visualisations-September 16, 2019.part2.rar Hands-on Three.js 3D Web Visualisations September 16, 2019 English | MP4 | AVC 1920×1080 | AAC 48KHz 2ch | 3h 46m | 968 MB eLearning | Skill level: All Levels Create stunning visualizations and 3D scenes using the Three.js library Three.js is the most popular JavaScript library for displaying 3D content on the web, giving you the power to display incredible models, games, music videos, and scientific/data visualizations in your browser and even on your smartphone! This course begins with a 3D beginner-level primer to 3D concepts and some basic examples to get you started with the most important features that Three.js has to offer. You’ll learn how to quickly create a scene, camera, and renderer and how to add meshes using the Geometry primitives included with the library. You’ll explore troubleshooting steps that will focus on some of the common pitfalls developers face. You’ll learn the very sophisticated animation system included with the library. The course concludes by introducing post-processing, essentially adding filters to your rendered scene, and GLSL, the shading language that is used by all materials included with the library. You’ll see how creating your materials is easier than you’d imagine using GLSL. By the end of this course, you’ll be able to quickly add advanced features to your 3D scenes, improve the way users interact with them, and make them look stunning. Learn Learn the basics of 3D applications: vertices, faces, meshes, cameras, and renderers Learn how to set up a Three.js web app: the scene, camera, and renderer Master the scene hierarchy and child-parent relationships, and how they affect the final location and orientation of objects Explore simple mesh shapes (such as boxes, spheres, cylinders, planes, and cones) using the Three.js library Learn how to source, create, and load complex assets, including textures Discover how to use the brilliant animation system that is part of the THREE.js library Add a post-processor to a rendered image, to make it look like an old film or a dot screenprint + Table of Contents 1 The Course Overview 2 Introducing the THREE.js website 3 D Basics 4 Your first THREE.js web page` 5 The THREE.js Editor 6 Debugging Your Pages 7 Let’s Keep It Simple – Starting with a Box 8 Materials One – Basic and Wireframe 9 Spheres and Cylinders 10 Materials Two – Lambert and Phong 11 Cones and Tori 12 Scene Hierarchy 13 Perspective Camera 14 Orthographic Camera 15 Dummy Cameras and Lerping 16 Complex Camera Paths 17 Ambient and Hemisphere Lighting 18 Directional and Point Lighting 19 Spot and RectArea Lighting 20 Adding Shadows to Your Scenes 21 Physically Correct Lighting 22 Online Sources of 3D Assets 23 Using Blender with THREE.js 24 The GLTFLoader Class 25 The FBXLoader Class 26 LatheGeometry and ExtrudeGeometry 27 The Basics of the Animation System 28 Skinned Meshes 29 Switching and Blending Animations 30 Splitting an Animation Clip 31 A WASD Control System for a Player Character 32 THREE.js Post Processing 33 Introducing GLSL – ShaderMaterial 34 Introducing GLSL – Vertex Shaders 35 Introducing GLSL – Importance of Noise Function 36 Introducing GLSL – Textures
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值