Tài liệu Beginning DirectX9
Lập trình game có thể nói là một công việc cực kỳ thú vị trong thế giới lập trình bởi
nó đem lại cho bạn cơ hội được tạo ra một thế giới ảo nơi mà những sinh vật
huyền bí, những vùng đất chưa hề được biết đến ngay cả trong những giấc mơ.
Liệu bạn có thể tìm thấy điều này ở một nơi nào khác? Với nó, bạn có thể đem đến
cho mọi người khả năng trở thành bất cứ một nhân vật nào, một con người nào mà họ
mong muốn và hơn cả là một môi trường để họ có thể sống theo đúng sở thích.
Cũng chính bởi thế mà ngành công nghiệp Game đã phát triển không ngừng, vượt qua
mọi giới hạn và kéo theo nó là phát triển của công nghệ phục vụ cho nó. Chỉ vài năm
trước đây, có lẽ ở cấp độ người sử dụng còn chưa hề biết đến các thiết bị thể hiện hình
ảnh 3D ngoại trừ các máy trạm đắt tiền SGI dựa trên nền tảng OpenGL. Tại thời điểm đó
có thể nói OpenGL mới chỉ đang ở thời kỳ phôi thai. Đến khi các máy tính cá nhân PC đã
được phổ biến hơn, OpenGL đã mở rộng nền tảng của mình và điều đó thực sự đã đem
đến một cú huých mạnh đầu tiên trong lịch sử phát triển game cũng như những ứng dụng
mô phỏng không gian 3D.
Tại thời điểm đó, Windows vẫn chưa phải là nền tảng tốt nhất để phát triển games, tuy
nhiên họ cũng rất nhanh chóng nhận ra những lợi nhuận từ ngành công nghiệp này. Chính
vì thế phiên bản DirectX đầu tiên cũng sớm được Microsoft tung ra. Tuy nhiên trong thời
gian đầu này thì sự phổ biến của nền tảng này vẫn còn rất hạn chế do OpenGL đã được
thừa nhận là phương thức chuẩn để phát triển đồ hoạ 3D trên môi trường Windows. Ngày
nay, hầu hết các game phát triển trên PC bán trên thị trường đều được xây dựng trên nền
tảng DirectX, nó đã giúp cho những game thủ có thể tận hưởng được một công nghệ đồ
hoạ tiên tiến và hiện thực nhất về thế giới.
L
Tóm tắt nội dung tài liệu: Tài liệu Beginning DirectX9
Beginning DirectX9 Dịch bởi TransTeam diễn đàn Gamedev.VN 2 © 2004 by Premier Press, a division of Course Technology. All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording, or by any information storage or retrieval system without written permission from Course PTR, except for the inclusion of brief quotations in a review. The Premier Press logo and related trade dress are trademarks of Premier Press and may not be used without written permission. DirectX is a registered trademark of Microsoft Corporation in the U.S. and/or other countries. © Microsoft Corporation, 2002. All rights reserved. All other trademarks are the property of their respective owners. Important: Course PTR cannot provide software support. Please contact the appropriate software manufacturer’s technical support line or Web site for assistance. Course PTR and the author have attempted throughout this book to distinguish proprietary trademarks from descriptive terms by following the capitalization style used by the manufacturer. Information contained in this book has been obtained by Course PTR from sources believed to be reliable. However, because of the possibility of human or mechanical error by our sources, Course PTR, or others, the Publisher does not guarantee the accuracy, adequacy, or completeness of any information and is not responsible for any errors or omissions or the results obtained from use of such information. Readers should be particularly aware of the fact that the Internet is an ever-changing entity. Some facts may have changed since this book went to press. Educational facilities, companies, and organizations interested in multiple copies or licensing of this book should contact the publisher for quantity discount information. Training manuals, CD-ROMs, and portions of this book are also available individually or can be tailored for specific needs. ISBN: 1-59200-349-4 Library of Congress Catalog Card Number: 2004090736 Printed in the United States of America 04 05 06 07 08 BH 10 9 8 7 6 5 4 3 2 1 Course PTR, a division of Course Technology 25 Thomson Place Boston, MA 02210 Senior Vice President, Course PTR Group: Andy Shafran Publisher: Stacy L. Hiquet Senior Marketing Manager: Sarah O’Donnell Marketing Manager: Heather Hurley Manager of Editorial Services: Heather Talbot Senior Acquisitions Editor: Emi Smith Associate Marketing Manager: Kristin Eisenzopf Project/Copy Editor: Karen A. Gill Technical Reviewer: Joseph Hall Retail Market Coordinator: Sarah Dubois Interior Layout: Marian Hartsough Cover Designer: Steve Deschene CD-ROM Producer: Brandon Penticuff Indexer: Sharon Shock Proofreader: Sean Medlock Beginning DirectX9 Dịch bởi TransTeam diễn đàn Gamedev.VN 3 Thông tin về tác giả WENDY JONES là người đã dành trọn niềm đam mê của cô ấy cho máy tính ngay từ lần đầu tiên cô được nhìn thấy chiếc máy Apple IIe khi còn học ở trường phổ thông. Kể từ khi tiếp cận với nó, cô ấy đã dành mọi khoảng thời gian rảnh rỗi vào công việc học lập trình BASIC và kỹ thuật đồ hoạ, vẽ những ý tưởng của mình lên giấy vẽ và thực hiện nó trên máy tính. Ngoài BASIC thì cô cũng đã lần lượt tiếp cận với các ngôn ngữ khác như Pascal, C, Java và C++. Nghề nghiệp của Wendy là một chuỗi thay đổi như chính sự phát triển của máy tính vậy, từ bỏ môi trường lập trình DOS, cô tự trang bị cho mình những kiến thức về lập trình Window và sao đó rất nhanh chóng nhảy sang thế giới .NET. Mặc dù các công ty Internet đem lại rất nhiều tiền, nhưng đó không phải là tất cả, chính vì thế Wendy đã mở rộng kỹ năng lập trình của mình sang lĩnh vực lập trình games và dồn tất cả sức lực của mình cho niềm đam mê đó. Wendy đã hiện thực hoá được niềm đam mê này khi cô nhận được một đề nghị làm việc cho công ty Atari’s Humongous Entertainment với tư cách là một lập trình viên. Trong xuốt quá trình làm việc ở Atari, cô ấy đã làm việc trên cả hai môi trường PC và máy chơi game cá nhân, bị quấn theo hàng loạt những thách thức mà công việc đó đem đến. Hiện tại Wendy đang làm việc các phần mềm dành cho PocketPC và trên những thiết bị chơi game cầm tay. Nếu bạn có bất cứ góp ý hay những câu hỏi về quyển sách này, bạn có thể liên hệ với cô theo địa chỉ mail: gadget2032@yahoo.com Beginning DirectX9 Dịch bởi TransTeam diễn đàn Gamedev.VN 4 Bố cục của sách Lời giới thiệu PHẦN I. NHỮNG KIẾN THỨC NỀN TẢNG Chương 1. DirectX là gì, tại sao và làm thế nào để sử dụng nó Chương 2. Ví dụ đầu tiên sử dụng DirectX Chương 3. Phông nền, khung hình, hoạt cảnh. PHẦN II. NHỮNG THÀNH PHẦN CƠ BẢN CỦA MỘT THẾ GIỚI 3D Chương 4. Những kiến thức cơ bản về 3D Chương 5. Ma trận, các phép biến đổi và phép xoay trong không gian Chương 6. Bảng mầu, vật liệu phủ và ánh sáng trong không gian Chương 7. Chia nhỏ và làm mịn đối tượng Chương 8. Vật thể, điểm chèn và các hiệu ứng PHẦN III. NHỮNG KIẾN THỨC BỔ XUNG Chương 9. Sử dụng DirectInput Chương 10. Hiệu ứng âm thanh bằng DirectSound Chương 11. Xây dựng một dự án mẫu PHẦN IV. PHỤ LỤC Phụ lục A. Giải đáp các bài tập cuối các chương Phụ lục B. Cách sử dụng CD-ROM Giải thích các thuật ngữ Chỉ mục các từ khoá Beginning DirectX9 Dịch bởi TransTeam diễn đàn Gamedev.VN 5 LỜI GIỚI THIỆU ập trình game có thể nói là một công việc cực kỳ thú vị trong thế giới lập trình bởi nó đem lại cho bạn cơ hội được tạo ra một thế giới ảo nơi mà những sinh vật huyền bí, những vùng đất chưa hề được biết đến ngay cả trong những giấc mơ. Liệu bạn có thể tìm thấy điều này ở một nơi nào khác? Với nó, bạn có thể đem đến cho mọi người khả năng trở thành bất cứ một nhân vật nào, một con người nào mà họ mong muốn và hơn cả là một môi trường để họ có thể sống theo đúng sở thích. Cũng chính bởi thế mà ngành công nghiệp Game đã phát triển không ngừng, vượt qua mọi giới hạn và kéo theo nó là phát triển của công nghệ phục vụ cho nó. Chỉ vài năm trước đây, có lẽ ở cấp độ người sử dụng còn chưa hề biết đến các thiết bị thể hiện hình ảnh 3D ngoại trừ các máy trạm đắt tiền SGI dựa trên nền tảng OpenGL. Tại thời điểm đó có thể nói OpenGL mới chỉ đang ở thời kỳ phôi thai. Đến khi các máy tính cá nhân PC đã được phổ biến hơn, OpenGL đã mở rộng nền tảng của mình và điều đó thực sự đã đem đến một cú huých mạnh đầu tiên trong lịch sử phát triển game cũng như những ứng dụng mô phỏng không gian 3D. Tại thời điểm đó, Windows vẫn chưa phải là nền tảng tốt nhất để phát triển games, tuy nhiên họ cũng rất nhanh chóng nhận ra những lợi nhuận từ ngành công nghiệp này. Chính vì thế phiên bản DirectX đầu tiên cũng sớm được Microsoft tung ra. Tuy nhiên trong thời gian đầu này thì sự phổ biến của nền tảng này vẫn còn rất hạn chế do OpenGL đã được thừa nhận là phương thức chuẩn để phát triển đồ hoạ 3D trên môi trường Windows. Ngày nay, hầu hết các game phát triển trên PC bán trên thị trường đều được xây dựng trên nền tảng DirectX, nó đã giúp cho những game thủ có thể tận hưởng được một công nghệ đồ hoạ tiên tiến và hiện thực nhất về thế giới. Những cần phải có những gì để tiếp cận công nghệ này? Những kinh nghiệm và kiến thức về lập trình C++ cũng như lý thuyết lập trình hướng đối tượng (OOP) sẽ giúp bạn có thể hiểu được tất cả những bài giảng được trình bày trong quyển sách này. Ngoài ra bạn cũng nên trang bị thêm cho mình một vài kỹ năng về toán học và hình hoạ, tuy nhiên hầu hết những khái niệm toán học sử dụng cũng sẽ được giải thích chi tiết. Những hiểu biết về Visual Studio .NET hay bất kỳ sản phẩm nào trong bộ Visual Studio cũng sẽ rất là hữu ích. L Beginning DirectX9 Dịch bởi TransTeam diễn đàn Gamedev.VN 6 Làm thế nào để sử dụng quyển sách này hiệu quả? Quyển sách này được chia làm 3 phần chính. Phần đầu tiên sẽ mô tả cở bản về DirectX, làm thế nào để thiết lập và chạy một ứng dụng sử dụng nền tảng này. Phần thứ hai sẽ cung cấp cho bạn những khái niệm cơ bản phục vụ quá trình thiết kế và xây dựng một môi trường 3D, kèm theo đó là giới thiệu những khái niệm về 3D và Direct3D. Phần 3 và phần cuối sẽ xoay quanh các kiến thức khác của nền tảng DirectX như xử lý âm thanh thông qua DirectSound, lấy các thông tin đầu vào từ người dùng thông qua DirectInput. Quyển sách kết thúc bằng một dự án minh hoạ nhỏ với hi vọng đem đến cho bạn một cái nhìn toàn cảnh hơn về tất các các kiến thức chúng ta đã học và áp dụng cụ thể chúng như thế nào. Nếu bạn đã từng làm quen với môi trường DirectX và cũng đã từng viết một vài ứng dụng sử dụng nền tảng này, bạn có thể bỏ qua phần một. Tôi nghĩ rằng bất kỳ ai khi mới tiếp cận với môi trường lập trình game và DirectX nên đọc quyển sách này một cách tuần tự để có thể hiểu hết được những khả năng mà DirectX có thể đem lại. Beginning DirectX9 Dịch bởi TransTeam diễn đàn Gamedev.VN 7 Chương 1. DirectX là gì, tại sao và làm thế nào để sử dụng nó Chương 2. Ví dụ đầu tiên sử dụng DirectX Chương 3. Phông nền, khung hình, hoạt cảnh. PHẦN I KIẾN THỨC NỀN TẢNG Beginning DirectX9 Dịch bởi TransTeam diễn đàn Gamedev.VN 8 DirectX là gì, Tại sao và Làm thế nào để sử dụng nó irectX về thực chất là một hệ thống các giao diện lập trình ứng dụng (API) phục vụ cho quá trình phát triển các game trên nền tảng hệ điều hành Windows. Nếu như tại thời điểm một vài năm trước, những người phát triển game thường phải vật lộn với những vấn đề nảy sinh từ sự không tương thích của phần cứng - không thể phát triển những sản phẩm game để tất cả mọi người đều có thể tận hưởng được những tính năng của game đó. Thì ngày nay, Microsoft đã đem tới một nền tảng DirectX. Nó cung cấp cho những người phát triển game một phương thức đơn nhất, một nền tảng thư viện API “sạch” (đã được chuẩn hoá) để họ có thể viết và chạy trên hầu hết các nền tảng mà không cần phải lo ngại nhiều về phần cứng của PC. Chỉ một vài năm sau khi phiên bản DirectX được đề xuất, số lượng game được phát triển trên nền tảng Windows đã tăng lên một cách nhanh chóng. Trong chương này, chúng ta sẽ đề cập tới các vấn đề: DirectX là gì vậy Tại sao nó lại hữu dụng đến thế Thành phần nào đã xây dựng nên nền tảng DirectX API DirectX là gì? DirectX là một tập hợp thư viện các hàm API được Microsoft thiết kế để cung cấp cho những người phát triển game một giao diện lập trình cấp thấp để liên kết tới các phần cứng của PC chạy trên hệ điều hành Windows. Phiên bản hiện tại của nó là 9.0(c), mỗi một đối tượng API của DirectX cung cấp một khả năng truy cập khác nhau tới từng loại phần cứng của hệ thống, nó bao gồm hệ thống đồ hoạ, âm thanh và kết nối mạng, tất cả chúng đều được xây dựng trên một giao diện chuẩn. Giao diện này cho phép những người phát triển có thể viết những game của họ bằng cách sử dụng tập hợp cách hàm này lại với nhau mà không cần phải quan tâm nhiều tới phần cứng mà nó sẽ được sử dụng. D CHƯƠNG 1 Beginning DirectX9 Dịch bởi TransTeam diễn đàn Gamedev.VN 9 Những thành phần tạo nên DirectX Hệ thống thư viện API của DirectX được phân chia ra làm nhiều thành phần nhỏ, mỗi thành phần này đảm nhiệm những nhiệm vụ khác nhau của hệ thống. Chúng có thể được sử dụng hoàn toàn độc lập với nhau, bạn có thể chỉ cần thêm những thành phần nào mà game của bạn cần tới mà thôi. Sau đây là danh sách các thành phần đó: DirectX Graphic. Thành phần này đảm nhiệm tất cả các chức năng kết xuất đồ hoạ của hệ thống. Nó cung cấp những hàm API để người dùng có thể quản lý quá trình vẽ 2D cũng như 3D, ngoài ra nó cũng hỗ trợ cả quá trình khởi tạo và xác lập độ phân giải cho game của bạn. DirectInput. Tất cả những gì người dùng nhập vào sẽ được quản lý bởi các hàm API trong thành phần này. Nó bao gồm khả năng hỗ trợ các thiết bị như bàn phím, chuột, gamepad, joystick. Với phiên bản mới nhất hiện nay cũng đã hỗ trợ cả các thiết bị tương tác thực (force-feedback) như cần lái, chân ga cho các game đua tốc độ. DirectPlay. Khả năng kết nối mạng được cung cấp cho những hệ thống game của bạn thông qua thành phần DirectPlay này. Những hàm phục vụ kết nối này đem đến cho bạn khả năng phát triển ứng dụng có thể giao tiếp với bất kỳ một máy nào khác, cho phép không chỉ một người có thể chơi game đó. DirectPlay đem đến cho bạn một giao diện lập trình cấp cao nhằm giúp bạn tránh khỏi những vấn đề khó khăn trong quá trình lập trình ứng dụng liên kết mạng. DirectSound. Nếu bạn muốn chèn thêm các hiệu ứng âm thanh hoặc nhạc nền, bạn sẽ cần phải sử dụng tới những hàm API do thành phần này cung cấp. Chức năng của DirectSound là cho phép bạn có thể tải và chơi một hoặc nhiều file nhạc dạng WAV cũng như toàn bộ khả năng điều khiển quá trình chơi nhạc đó. DirectMusic. Thành phần này mang đến cho bạn khả năng tạo các bản nhạc “động” (tại thời điểm chương trình chạy, không cần phải lưu trữ trong cơ sở dữ liệu của game). Nó có khả năng hỗ trợ hầu hết các chức năng chính của một phần mềm chơi nhạc midi như tự chạy lại theo một qui trình đã xác lập, biến đổi âm lượng để phù hợp với hoạt cảnh trong game, thay đổi nhịp của giai điệu và nhiều chức năng cao cấp khác. DirectShow. Bạn có thể cắt một hoạt cảnh phim hoặc lồng ghép âm thanh và game của mình thông qua thành phần này. AVI, MP3, MPEG và ANF chỉ là một trong số rất nhiều các loại định dạng file mà DirectShow hỗ trợ. Với DirectShow, bạn sẽ không phải tải tất cả các đối tượng file này lên bộ nhớ, thay vào đó là truy cập trực tiếp dữ liệu trên ổ cứng hoặc CD-ROM. DirectSetup. Sau khi game của bạn đã hoàn thành, bạn sẽ muốn phát hành. DirectSetup cung cấp cho bạn những chức năng giúp ứng dụng có thể tự động cài đặt những phiên bản DirectX mới nhất lên hệ thống của người sử dụng. Chú ý: Hệ thống đồ hoạ DirectX bao gồm toàn bộ các chức năng của cả DirectDraw và Direct3D. Phiên bản DirectX 7.0 là phiên bản cuối cùng phân tách hai thành phần này thành hai đối tượng độc lập. Beginning DirectX9 Dịch bởi TransTeam diễn đàn Gamedev.VN 10 Tại sao DirectX lại cần thiết? Trước khi hệ điều hành Windows được phát hành, các lập trình viên chủ yếu phát triển các game trên nền tảng hệ điều hành DOS. Đấy là một hệ điều hành đơn nhiệm, không hỗ trợ giao diện đồ hoạ (non-GUI) và cách duy nhất để thực hiện các thao tác đồ hoạ này là truy cập trực tiếp vào phần cứng và thực thi chúng. Điều này đem đến cả những lợi ích cũng như những vấn đề khó khăn cần giải quyết. Ta có thể ví dụ ra, bởi vì sử dụng cách truy cập trực tiếp giữa mã game và phần cứng, lập trình viên có thể có được toàn bộ sức mạnh cũng như quyền điều khiển của hệ thống, điều nay đem đến khả năng hoạt động với hiệu suất và chất lượng cao của hệ thống game. Tuy nhiên, mặt trái của vấn đề là những nhà phát triển game này sẽ phải tự xây dựng cho mình những thư viện h ... 4, 2 ); pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 8, 2 ); pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 12, 2 ); pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 16, 2 ); pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 20, 2 ); pd3dDevice->EndScene(); // biểu diễn ra front buffer pd3dDevice->Present( NULL, NULL, NULL, NULL ); } Có 3 biến được khai báo ở đầu của hàm render là objMat, matRotate, và finalMat. Những biến này là các ma trận lưu trữ thông tin về hình hộp. Phần trước bạn đã được học cách đưa một ma trận về dạng đồng nhất , và ở đây ma trận objMat cần được làm như vậy mỗi lần hàm render được gọi. Điều đó nhằm mục đich làm cho phép xoay luôn thực hiện ở gốc tọa độ. Như vậy objMat biểu diễn vị trí thực của hình hộp. D3DXMatrixIdentity(&objMat); Ma trận thứ hai là matRotate, chứa thông tin về phép xoay hình hộp. Bởi vì hình hộp cần được xoay liên tục, do đó bạn cần cập nhật mới ma trận matRotate cho mỗi lần xoay với một vị trí mới của hình hộp. Phép xoay được thực hiện thông qua D3DXMatrixRotationY, là một hàm trong thư viện D3DX. Những hàm xoay trong thư viện D3DX sẽ viết đè thông tin trên ma trận qua mỗi lần xoay, vì thế mà bạn không cần gọi D3DXMatrixIdentity để đồng nhất hóa ma trận này. D3DXMatrixRotationY(&matRotate, timeGetTime()/1000.0f); Hàm timeGetTime sử dụng thời gian hiện tại và chia cho 1000.0f để xoay hình hộp trơn chu hơn. Tóm lại, bạn có hai ma trận, một cái biểu diễn vị trí của đối tượng và cái kia biểu diễn sự vận động của đối tượng, bạn cần nhân hai ma trận này với nhau để có được ma trận cuối cùng biểu diễn qua finalMat. Ma trận kết quả quy đổi hình hộp về không gian thực qua hàm SetTransform dưới đây: pd3dDevice->SetTransform(D3DTS_WORLD, &finalMat); Beginning DirectX9 Dịch bởi TransTeam diễn đàn Gamedev.VN 89 Kết quả trả về từ SetTransform là một hình hộp được đặt ở vị trí mới và định hướng trong không gian thực. Hàm render sẽ vẽ hình hộp qua các lời gọi DrawPrimitive. Bạn có thể tìm thấy mã nguồn về các phép xoay đối tượng trong thư mục chapter5\example2 trên đĩa CD. Tâm của phép xoay Tâm của phép xoay một đối tựợng phụ thuộc vào trục mà nó xoay quanh. Nếu một đối tượng, ví như hình hộp trong hình 5.6 đã xoay , tâm xoay của nó làm cho nó quay tròn xung quanh gốc tọa độ. Nếu một đối tựợng được tịnh tiến ra xa gốc tọa độ và dọc theo một trục nào đó, thì tâm xoay của cũng dịch chuyển dọc trục đó làm cho đối tượng bị dịch chuyển sang vị trí khác trong quá trình thực hiện phép xoay. Nhìn vào hinh 5.7, ta thấy một hình hộp được tịnh tiến dọc theo trục X và Y trước khi bị xoay. Khi hình hộp đó được xoay quanh trục X, thì nó cũng bị tịnh Hình 5.7: Hình hộp được xoay quanh trục X tiến trong suốt quá trình xoay này. sau khi được tịnh tiến ra xa gốc tọa độ Để thay đổi tâm phép xoay, bạn cần phải tịnh tiến đối tượng ra xa gốc tọa độ trước khi tiến hành phép xoay. Đoạn code sau cho thấy cách mà tâm xoay thay đổi khi tịnh tiến đổi tượng. /************************************************************************ * render ************************************************************************/ void render(void) { // xóa back buffer về màu đen pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255,255,255), 1.0f, 0 ); pd3dDevice->BeginScene(); pd3dDevice->SetStreamSource( 0, vertexBuffer, 0, sizeof(CUSTOMVERTEX) ); pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX ); // tịnh tiến đối tượng ra xa gốc tọa độ D3DXMatrixTranslation(&matTranslate, 64.0f, 0.0f, 0.0f); // cài đặt phép quay D3DXMatrixRotationY(&matRotate, timeGetTime()/1000.0f); // Nhân ma trận tịnh tiến và ma trận xoay để có ma trận objMat D3DXMatrixMultiply(&objMat, &matTranslate, &matRotate); // thực hiện phép biến đổi trong không gian thực pd3dDevice->SetTransform(D3DTS_WORLD, &objMat); pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 ); pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 4, 2 ); pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 8, 2 ); pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 12, 2 ); Beginning DirectX9 Dịch bởi TransTeam diễn đàn Gamedev.VN 90 pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 16, 2 ); pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 20, 2 ); pd3dDevice->EndScene(); // đưa kết quả ra front buffer pd3dDevice->Present( NULL, NULL, NULL, NULL ); } Sự thay đổi lớn nhất trong hàm render là hàm D3DXMatrixTranslation. Hàm này dịch chuyển hình hộp ra xa gốc tọa độ 64 đơn vị. Trong trường hợp này, hình hộp sẽ được tịnh tiến ra xa gôc tọa độ dọc theo trục X và sau đó mới xoay. Hai ma trận được dùng ở đây là : matTranslate và matRotate. Hai ma trận này được nhân với nhau để có ma trận objMat, chứa vị trí sau cùng của hình hộp. Kết quả là ta có một hình hộp được xoay ở cách xa gốc tọa độ Phép tỉ lệ Phép tỉ lệ cho phép bạn thay đổi kích thước đối tượng bằng cách nhân các vecto của đối tượng với một lượng nào đó. Để thực hiện phép tỉ lệ trên đối tượng, bạn cần tạo một ma trận chứa các hệ số tỉ lệ. Những hệ số này cho biết các vecto sẽ được phóng to hay thu nhỏ bao nhiêu. Như đã đề cập ở trên, các vị trí 1, 6, 11 là các hệ số tỉ lệ theo các phương X, Y và Z. Mặc định, các số đó là 1.0f nghĩa là các đối tượng có kích thước như nó vốn có. Thay đổi bất kì hệ số nào sẽ làm thay đổi kích thước của đối tượng. Nếu các hệ số này lớn hơn 1.0f thì đối tượng sẽ được phóng to ra, ngược lại, nếu hệ số này nhỏ hơn 1.0f thì đối tượng sẽ bị thu nhỏ lại. ⎥⎥ ⎥⎥ ⎦ ⎤ ⎢⎢ ⎢⎢ ⎣ ⎡ 16151413 12109 875 442 Z Y X Như đã đề cập ở trên, phép tỉ lệ được điều khiển thông qua các giá trị trong ma trận. Để tạo một ma trận tỉ lệ, ta chỉ cần định nghĩa một ma trận đồng nhất và thay đổi các hệ số như đã nói ở trên. Bạn vừa có thể tự mình thay đổi các giá trị này vừa có thể sử dụng thông qua hàm D3DXMatrixScaling như định nghĩa dưới đây: D3DXMATRIX *D3DXMatrixScaling( D3DXMATRIX *pOut, FLOAT sx, FLOAT sy, FLOAT sz ); Hàm D3DXMatrixScaling cần 4 đối số: ■ pOut. Con trỏ đến đối tượng D3DXMATRIX chứa ma trận tỉ lệ ■ sx. Hệ số tỉ lệ theo phương X ■ sy. Hệ số tỉ lệ theo phương Y ■ sz. Hệ số tỉ lệ theo phương Z Đoạn code sau cho thấy cách dùng hàm D3DXMatrixScaling để tăng gấp đôi kích thước một vật thể. D3DXMATRIX matScale; // đặt hệ số tỉ lệ Beginning DirectX9 Dịch bởi TransTeam diễn đàn Gamedev.VN 91 D3DXMatrixScaling(&matScale, 2.0f, 2.0f, 2.0f); // Nhân ma trận đối tượng với ma trận tỉ lệ D3DXMatrixMultiply(&objMat, & objMat, &matScaling); Biến objMat ở trên biểu diễn ma trận gốc của đối tượng. nhân ma trận của đối tượng với ma trận tỉ lệ ta sẽ có thể thu phóng đối tượng khi vẽ. Thứ tự trong các phép tính toán ma trận Thứ tự trong các phép toán là rất quan trọng. Ví dụ như, nếu bạn muốn xoay một đối tượng quanh tâm của nó và sau đó dịch chuyển nó đi đâu đó, thì trước tiên bạn cần tính toán với ma trận xoay trước tiếp đó là đến ma trận tịnh tiến. Nếu hai phép tính này được đổi chỗ cho nhau, thì đối tượng sẽ được tịnh tiến đến 1 vị trí khác sau đó mới được xoay quanh gốc tọa độ. Điều này có thể làm cho đối tượng được đặt ở một ví trí khác và hướng theo một hướng khác trong không gian. Đoạn code sau chỉ ra trình tự đúng để thực hiện phép xoay và tịnh tiến đối tượng: D3DXMATRIX objRotate; D3DXMATRIX objTranslation; D3DXMATRIX objFinal; // phép xoay D3DXMatrixRotationY(&objRotate, D3DXToRadian(45)); // phép tịnh tiến D3DXMatrixTranslation(&objTranslation, 1.0f, 0.0f, 0.0f); // nhân ma trận xoay và ma trận tịnh tiến với nhau D3DXMatrixMultiply(&objFinal, &objRotate, &objTranslation); // thực hiện phép biến đổi trong không gian thực pd3dDevice->SetTransform(D3DTS_WORLD, &objFinal); Bước thứ nhất là tạo ma trận xoay đối tượng, objRatate. Sử dụng hàm D3DXMatrixRotationY như trên, đối tượng sẽ được quay một góc 45 độ quanh trục Y. Tiếp theo ta tịnh tiến đối tượng đã xoay một đơn vị về bên phải bằng cách sử dụng hàm D3DXMatrixTranslation. Cuối cùng, ta tạo ra ma trận biến đổi bằng cách nhân ma trận xoay và ma trận tịnh tiến với nhau với hàm D3DXMatrixMultiply. Nếu ma trận xoay và ma trận được đảo chỗ cho nhau (hoán vị) trong lời gọi hàm D3DXMatrixMultiply, thì phép tịnh tiến sẽ được thực hiện trước phép xoay, và đối tượng bị rời sang vị trí khác. Tạo một camera bằng các phép chiếu Bạn có thể tạo ra một camera trong Direct3D bằng cách định nghĩa một ma trận cho bước (projection transformation). Ma trận này định nghĩa một vùng nhìn cho camera, hệ số co, mặt phẳng clipping xa và gần. Sau khi bạn đã tạo được ma trận chiếu, bạn thiết lập nó thông qua hàm SetTransform. Bạn có thể thấy rằng, hàm SetTransform đã được sử dụng ở ví dụ trước. SetTransform, định nghĩa ở dưới đây, cho phép thiết lập ma trận cho các bước của hệ thống chuyển đổi hình học. Ví dụ như, khi bạn thiết lập ma trận cho một camera, cũng có nghĩa là bạn đang quy định cho scene sẽ được quan sát ra sao trong suốt giai đoạn chiếu. Giai đoạn này cũng là giai đoạn cuối cùng của hệ chuyển đổi hình học, nó quy định cách mà khung cảnh 3D sẽ được render dưới dạng 2D. HRESULT SetTransform( Beginning DirectX9 Dịch bởi TransTeam diễn đàn Gamedev.VN 92 D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX *pMatrix ); Hàm SetTransform cần 2 đối số: ■ State. Xác định giai đoạn của hệ chuyển đổi hình học cần chỉnh sửa. ■ pMatrix. Con trỏ có cấu trúc D3DMATRIX được dùng để thiết lập cho giai đoạn trên. Đoạn code sau cho thấy cách tạo và định nghĩa một ma trận cho giai đoạn chiếu. D3DXMATRIX matProj; // ma trận chiếu /********************************************************************** * createCamera * tạo camera ảo ***********************************************************************/ void createCamera(float nearClip, float farClip) { // Xác định vùng nhìn, hệ số co và mặt phẳng clipping xa, gần D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 640/480, nearClip, farClip); // thiết lập ma trận matProj cho giai đoạn chiếu pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj); } Thay vì tự mình tạo một ma trận chiếu, ta đã dùng hàm D3DXMatrixPerspectiveFovLH do D3DX cung cấp. Hàm này tạo một ma trận đầu ra chứa trong matProj được khai báo ở trên, nó cho phép bạn xác định góc nhìn phối cảnh, hệ số co, và mặt phẳng clipping chỉ trong một lời gọi hàm. Sau khi bạn đã tạo đươc ma trận chiếu, bạn có thể thiết lập nó cho hệ chuyển đổi hình học thông qua hàm SetTransform. Bởi vì ma trận này tác dụng lên giai đoạn chiếu, cho nên tham số đưa vào là D3DTS_PROJECTION. Vị trí và hướng của camera Đến thời điểm này, bạn đã có thể sử dụng được camera rồi. Camera tác động lên mọi thứ trong khung cảnh cũng giống như là các đối tượng được chuyển qua giai đoạn chiếu trong hệ chuyển đổi hình học vậy. Chỉ có một điều là, camera của ta đang được đặt ở gốc tọa độ. Bởi vì camera trong thế giới thực là một vật thể có thể chuyển động được, nên ta cũng cần làm cho camera ảo có thể làm được giống như vậy. Nó cần có khả năng chuyển động trong khung cảnh và cũng có thể thay đổi hướng nhìn. Để đạt được 2 tiêu chí này, bạn cần thay đổi ma trận tương ứng với giai đoạn View transformation. Mặc định, ma trận này được đặt là ma trận đồng nhất cố định camera ảo ở gốc tọa độ. Để thay đổi vị trí và hướng của camera, bạn cần tạo một ma trận mới. Cách đơn giản nhất để làm điều đó là sử dụng hàm trợ giúp D3DXMatrixLookAtLH của D3DX. Hàm D3DXMatrixLookAtLH cho phép bạn chỉ ra vị trí của camera (định nghĩa như một vecto dạng D3DXVECTOR3), nơi mà camera nhìn vào (cũng dạng D3DXVECTOR3), và hướng của camera (cũng là dạng D3DXVECTOR3). Đoạn code sau chỉ ra cách tạo ma trận quan sát (view). D3DXMATRIX matView; // ma trận view /************************************************************************* * pointCamera * đặt điểm nhìn cho camera thông qua 1 vecto *************************************************************************/ Beginning DirectX9 Dịch bởi TransTeam diễn đàn Gamedev.VN 93 void pointCamera(D3DXVECTOR3 cameraPosition, D3DXVECTOR3 cameraLook) { D3DXMatrixLookAtLH ( &matView, &cameraPosition, // vị trí camera &cameraLook, // điểm nhìn &D3DXVECTOR3 (0.0f, 1.0f, 0.0f)); // hướng lên trên // thiết lập ma trận này cho giai đoạn view pd3dDevice->SetTransform (D3DTS_VIEW, &matView); } Hàm pointCamera cần hai đối số: cameraLook và cameraPosition. Biến cameraPosition chứa vị trí hiện tại của camera. Ví dụ như, nếu camera được đặt ở cách gốc tọa độ 2 đơn vị dọc theo trục Y, cameraPosition sẽ có dạng (0.0f, -2.0f, 0.0f). Biến cameraLook thông báo cho camera nơi cần hướng tới và nó có quan hệ với vị trí đặt camera. Ví dụ như, nếu coi camera đặt ở vị trí10 đơn vị dương dọc theo trục Y,10 đơn vị âm theo trục Z và tưởng tượng rằng ta muốn camera hướng về phía gốc tọa độ. Bởi vì lúc này camera đã được đặt ở phía trên so với gốc tọa độ, do đó muốn thấy được gốc tọa độ nó cần phải nhìn xuống dưới. Ta cần thiết lập cho vecto cameraLook giá trị là (0.0f, - 10.0f; 0.0f), điều này có nghĩa là camera hướng thẳng theo trục Y và hướng xuống dưới. Camera lúc đó có thể nhìn các thấy đối tượng đặt ở gốc tọa độ và từ phía trên đầu của chúng. Ma trận cuối cùng mà D3DXMatrixLookAtLH tạo ra được lưu trữ trong matView và được thiết lập cho giai đoạn view của hệ chuyển đổi. Giá trị D3DTS_VIEW được truyền cho hàm SetTransform thông báo cho Direct3D rằng ma trận view cần được cập nhật lại. Beginning DirectX9 Dịch bởi TransTeam diễn đàn Gamedev.VN 94 Tổng kết chương Trong chương này, ta đã giới thiệu những khái niệm chung cần thiết khi xây dựng một ứng dụng 3D. Khi bạn muốn tạo một chương trình quan sát mô hình, hay một game nhập vai góc quay thứ nhất, ma trận và các phép biến đổi chính là nền móng mà game của bạn được xây dựng trên đó. Những gì bạn đã được học Trong chương này, bạn đã được học: ■ Cách chuyển các đối tượng 3D qua hệ chuyển đổi hình học. ■ Ma trận là gì khi nào và làm thế nào sử dụng chúng ■ Cách dịch chuyển và xoay các đối tượng. ■ Tại sao thứ tự trong phép nhân ma trận lại quan trọng đến vậy. ■ Cách tạo và sử dụng camera để quan sát các đối tượng 3D. Câu hỏi kiểm tra Bạn có thể tìm thấy đáp án cho phần này và phần bài tập tự làm trong phụ lục “Đáp án phần bài tập cuối chương”. 1. Chỉ mục của đối tượng được lưu trữ trong bộ đệm (buffer) nào ? 2. Ma trận là gi? 3. Những bước trong hệ chuyển đổi hình học? 4. Ma trận đồng nhất dùng để làm gì? 5. Thay đổi hệ số co của camera tác động đến phần nào của hệ chuyển đổi hình học? Bài tập tự làm 1. Sử dụng hàm D3DXMatrixMultiply, để xoay đối tượng và sau đó tịnh tiến nó 5 đơn vị theo trục X. 2. Viết một hàm render xoay liên tục một đối tượng quanh trục Y. Beginning DirectX9 Dịch bởi TransTeam diễn đàn Gamedev.VN 95 (Chuong 6...)
File đính kèm:
- tai_lieu_beginning_directx9.pdf