Mach2
16-05-2003, 00:54
Introduction
Khi lập trình game, ý tôi muốn nói là lập trình game nghiêm túc theo đúng nghĩa của nó, tức là không phải dùng phần mềm tạo game hay dùng một engine nào đó có sẵn, người lập trình chắc chắn phải "đụng đến" vấn đề lập trình đồ hoạ. Khi đó họ sẽ phải chọn lựa giữa 2 bộ thư viện API đồ họa phổ biến nhất hiện nay. Đó là OpenGL và Direct3D. Sử dụng thư viện nào, thư viện nào tốt hơn trong hai bộ thư viện này đã và đang luôn luôn là câu hỏi gây nên vô số tranh cãi. Thông thường các lập trình viên thường chia thành hai trường phái đối lập hẳn nhau. Một cho rằng DirectX là con đường duy nhất dẫn đến La Mã và còn lại thì ngã về OpenGL. Trong bài viết này, mục đích của tôi là phân tích một số mặt mạnh và yếu của hai bộ thư viện trên thông qua một số kinh nghiệm (ít) và thông tin thu thập được trong thời gian qua (của người khác-nhiều). Tôi cũng không có ý định đưa chi tiết cấu trúc cũng như hướng dẫn cách sử dụng chúng trong bài viết này. Tuy nhiên các bạn có thể tìm thấy vô số các bài viết, hướng dẫn và sách vở về chúng trên mạng nếu muốn. Links về Direct3D và OpenGL đã rất nhiều lần được CrazyBabe và tôi đưa lên diễn đàn này.
Chú thích thêm: Tôi là một thành viên của trường phái OpenGL. Tôi bắt đầu nghiên cứu OpenGL trong khoảng 2 năm nay và chỉ biết rất ít về Direct3D, do đó các kiến thức và hiểu biết của tôi về Direct3D chỉ có hạn và vì vậy các nhận xét về Direct3D phần lớn chỉ các thông tin thu thập từ sách vở. Vậy nếu bạn thấy rằng tôi hơi ngả về OpenGL thì cũng xin châm chước cho và đừng làm bài viết này thành ra một cuộc tranh cãi nhé. Cám ơn rất nhiều.
Direct3D
Trong một thời gian rất dài, Direct3D không được xem không thể là đối thủ của OpenGL trong mặt trận game. Tuy nhiên gần đây, sau hàng loạt cố gắng và cải tiến đáng kể của Microsoft, Direct3D đã từng bước giàng được một thị phần đáng kể trong thế giới phát triển game hiện nay, nhất là sau sự ra đời của DirectX7, “kẻ huỷ diệt” của OpenGL. Trái hẳn với các phiên bản Direct3D đầy bọ trước, đồ hoạ trong DirectX7 được tách thành 2 phần riêng biệt: DirectDraw và Direct3D, xử lý các hình ảnh 2D và 3D, theo thứ tự đó. Cùng với hàng loạt cải tiến mới và hiệu quả, DirectX từng bước trở thành một chuẩn mực và lựa chọn đầu tiên của các lập trình viên game trên nền Windows.
Direct3D được xây dựng trên nền kiến trúc COM. Chắc hẳn các bạn đã biết đến khái niệm này. Nói nôm na, cho dễ hiểu, Direct3D làm việc bằng các class, tức hướng đối tượng. Với một số lượng class “khấm khá”, Direct3D hỗ trợ hầu hết các công việc mà một lập trình viên cần, ngoài ra nó còn đặt ra và hỗ trợ các định dạng của riêng nó như mô hình mesh (.X) và texture (.dds). Điều này đặt biệt “hay ho”. Một điều đáng lưu ý nữa là Direct3D hỗ trợ chi tiết toàn bộ rendering pipeline của nó. Bạn có thể can thiệp ngay cả vào một số phần của rendering pipeline.
Phiên bản đang được sử dụng phổ biến hiện nay của dòng DirectX, DirectX8, đã bổ sung vào hai thành phần đang được xem là “mode” trong giới đồ hoạ 3D. Đó là Programmable Pixel và Vertex Shaders. Đương nhiên khó mà giải thích được hai khái niệm trên một cách ngắn gọn, tuy nhiên có thể nói ngắn gọn là với hai công cụ trên, bạn có thể sửa đổi một số phần trong rendering pipeline của Direct3D bằng một số mã lệnh gần giống assembly. Nghe thì có vẻ không ghê gớm gì, nhưng nếu bạn đã từng bị kẹt như tôi trong khi đang làm một số hiệu ứng trong OpenGL thì việc can thiệp được “một tí gì” vào rendering pipeline quả là một phép thần kỳ…. Tuy nhiên, cũng phải nói thêm rằng, không phải card đồ hoạ nào cũng support hai công cụ trên đâu. Ít nhất thì cũng phải card kha khá như ATI 8500, GF3, GF4Ti,… trở lên. Đáng buồn thay.
Direct3D trong phiên bản DX8 bổ sung hàng tá hỗ trợ trong việc tạo hiệu ứng, điều này đã qua mặt OpenGL, vốn được cập nhật khá chậm chạp. Phiên bản DX9 hiện nay hỗ trợ vô số hiệu ứng. Có thể nói, với Pixel Shaders và Vertex Shaders, tất cả những gì bạn cần hiện nay là một card đồ họa tốt. Thế thôi, sau đó thì… tha hồ tưởng tượng!!!
Microsoft là một đại gia. Điều đó thì ai cũng biết. Họ hẳn là có liên hệ chặt chẽ với các nhóm phát triển phần cứng (như nVidia hay ATI,… ), vì vậy về chuyện ứng dụng phần cứng tối ưu hay tận dụng sức mạnh của các card đồ hoạ mới nhất thì bạn khỏi phải lo. Phần mềm đi trước phần cứng (như trường hợp DX9 ra đời cả mấy tháng nay mà hiện nay vẫn chưa có game nào tận dụng hết sức mạnh của nó) là chuyện bình thường.
Tuy nhiên, Direct3D không phải là không có điểm yếu. Người ta thường nói, “lắm tài thì nhiều tật”. Điểm mạnh của Direct3D cũng là điểm yếu của nó.
Direct3D quá chi tiết, mà chi tiết quá thì thế nào cũng phức tạp. Điểm yếu đầu tiên của Direct3D là quá phức tạp. Bạn phải mất khoảng từ 200 dòng code để có thể bắt tay vào vẽ bằng Direct3D. Đối với các bạn mới bắt đầu học thì chuyện này cũng tương tự như chuyển từ Turbo C sang Visual C++… Tuy nhiên, điều đó cũng chẳng đáng gì so với việc bạn phải có một số kiến thức về đồ hoạ máy tính lý thuyết (lý thuyết nhá, ý tôi muốn nói là ma trận, vector, nội suy,… những thứ khô khan đối với dân tin) bởi Direct3D quá chi tiết, và bạn cần phải hiểu rõ ràng tất cả nhưng hàm và phương thức chi tiết này. Điều này dẫn đến code của bạn sẽ rất dễ bị bọ chui vào nếu không cẩn thận.
Direct3D do Microsoft phát triển. Và vì bạn đã biết Microsoft chẳng ưa gì Linux hay Unix, (Bill Gate thậm chí còn muốn chúng “chết” nhanh nữa là khác), vì vậy Direct3D chỉ chạy trên Windows, và chỉ Windows mà thôi. Đừng hòng chú chim cánh cụt mó tay cùi vào nhá. Bạn chọn Direct3D, thế thì phải chắc chắn là game bạn viết chỉ chạy trên Windows thôi nhá. Đừng mong gì recompile lại trên Linux hay Unix.
Direct3D hỗ trợ game tốt, điều này thì ngay cả dân trung thành hâm mộ OpenGL từ bao nhiêu năm qua dù si mê cuồng vọng OpenGL đến mấy thì cũng phải công nhận. Tuy nhiên, trong mặt trận khác như đồ hoạ kỹ thuật, CAD, hay ứng dụng đòi hỏi 3D thì Direct3D chưa hề có chỗ chen chân vào.
Một điểm nữa làm cho Direct3D thêm phần rắc rối cuộc đời là do sự cống hiến nhiệt tình của Microsoft. Cứ mỗi phiên bản DirectX khác nhau là bác Bill nhà ta xây dựng lại, cập nhật thêm tùm lum nào là đối tượng mới, nào là hàm mới. Chuyện này nói ra thì cũng tốt bởi vì cuối cùng là lập trình viên được lợi thôi, tuy nhiên làm như thế thì các chương trình viết dễ bị không tương thích lắm. Ví dụ như bạn viết game trên nền DirectX7, đến khi chạy trên nền DirectX9 sẽ bị không tương thích nếu như lỡ dại xài một số hàm mà DirectX9 không còn hỗ trợ (như ảnh stereo chẳng hạn), lúc đó thì khóc dở mếu dở. Microsoft đã thông báo là phiên bản tiếp theo DirectX X (!!!,đừng nhầm với *** nhá) ít nhất sẽ không ra mắt cho tới giữa năm sau do DirectX9 hiện đã quá đủ đối với phần cứng hiện nay. Hy vọng họ không “đẻ” ra thêm cái gì mới, DirectDraw, Direct3D và DirectSurface hiện nay đã đủ phức tạp quá rồi còn gì.
Tương lai của Direct3D vẫn còn nằm ở phía trước và chắc chắn rằng (hu hu!!!) nó sẽ trở thành một chuẩn mực của tất cả game chạy trên nền Windows. Nếu bạn chọn Direct3D, bạn đã mua được một chiếc vé bay vào tương lai của anh Bill rồi đấy.
OpenGL
OpenGL đã được ra đời và phát triển hơn 10 năm nay. Với một thời gian dài như vậy, rõ ràng nó đã chứng tỏ được sự ổn định và hấp dẫn của mình rồi, bởi không ai lại đi xài một bộ thư viện quá già nua như thế mà không có lý do chứ? OpenGL được phát triển bởi SGI từ 10 năm trước, với mục đích là tạo nên một bộ thư viện đồ hoạ ổn định lâu dài và hướng đến tương lai. Xin nói rõ là: tương lai của 10 năm trước, tức OpenGL nhắm vào các hệ thống đồ hoạ lớn và đắt tiền như các máy trạm SGI chuyên dùng vào đồ họa. Trong 10 năm đó, OpenGL phát triển rất chậm (cho đến hiện nay mới chỉ là version 1.4), trong khi tốc độ của các card đồ hoạ bình dân (là loại card mà chúng ta hiện đang sử dụng) đã vượt xa mức tưởng tượng của các nhà phát triển OpenGL 10 năm trước. Với một thực tế như thế, có thể nói thời hoàng kim của OpenGL đã đến và trôi qua từ lâu.
Thế nhưng, không phải vì thế mà nói OpenGL không đi kịp thời đại. OpenGL vẫn gắn bó mật thiết với sự phát triển của phần cứng thông qua ARB (Architecural Review Board). Đây là một hội đồng bao gồm các công ty và nhà phát triển phần cứng có liên quan đến đồ hoạ, có thể kể như 3D Lads, SGI, nVidia, ATI, Microsoft, id Software hay Intel nữa. Nhóm này chuyên đưa ra các chuẩn và mở rộng (extensions) của OpenGL để bộ thư viện này không bị lỗi thời với nhịp đua của thời đại. Có thể nói là các extensions là cầu nối để OpenGL có thể bắt kịp với hiện tại, là những bộ chip xử lý đồ hoạ mới được cập nhật với bao nhiêu chức năng cao cấp, điều mà những người phát triển OpenGL từ thuở sơ khai đã chưa hề tưởng tượng được.
OpenGL được phát triển từ lâu, vào thời mà OOP vẫn chưa được thịnh hành, do đó nó đơn thuần chỉ là một bộ thư viện API bao gồm các nhiều hàm đồ hoạ. OpenGL có khoảng 200 hàm đồ hoạ chuẩn, và khoảng chừng đó số lượng các hàm extensions. Con số này trông có vẻ nhiều, tuy nhiên không thấm vào đâu so với DirectX. Các hàm của OpenGL chỉ thuần tuý là hàm, tức là không dùng class, tuy nhiên bạn có thể tạo class của bạn trên cơ sở các hàm này để tạo nên ứng dụng OpenGL bằng OOP của mình. Sử dụng OpenGL như thế nào hoàn toàn tuỳ thuộc vào bạn.
Các hàm và khai báo của OpenGL đặc biệt thân thiện với người sử dụng. Các tên hàm như glColor3f hoàn toàn có thể nói rõ bản chất hoạt động của hàm. “gl” chỉ hàm của OpenGL, “Color” chỉ rõ đây là hàm khai báo màu sắc, “3” chỉ số thành phần màu sắc (R, G, B), trong khi “f” chỉ loại kiểu dữ liệu đưa vào là float. Việc sử dụng ít hàm và tên hàm thân thiện đã làm cho việc lập trình bằng OpenGL đơn giản, ngắn gọn và dễ debug hơn nhiều so với Direct3D.
OpenGL có nhiều điểm mạnh vượt trội. Điều đầu tiên có thể nói về OpenGL là tính tương tích của bộ thư viện này rất cao. Bạn có thể sử dụng OpenGL trong hầu hết các hệ khác nhau như Linux, Unix và dĩ nhiên cả Windows. Bất cứ trình dịch bằng ngôn ngữ lập trình nào cũng có thể dùng OpenGL bởi nó được cung cấp dưới dạng API trong các thư viện động dll, và điều quan trọng nhất là các thư viện động này đã được tích hợp sẵn vào Windows. Bạn không cần cài đặt OpenGL, chỉ cần include file header của OpenGL vào và voila, viết code thoải mái.
OpenGL với sự giúp đỡ của ARB đã bắt kịp với nhịp tiến của các card đồ hoạ mới nhất hiện nay. OpenGL support tất cả những gì Direct3D hỗ trợ, bao gồm cả Pixel Shaders và Vertex Shaders, tuy nhiên vẫn cũng chỉ các card như GF3, GF4Ti hay ATI 8500 mới có thể dùng được các chức năng này (buồn 5 phút cho những kẻ sử dụng GF4MX như tôi). Bởi vì ARB bao gồm nhiều công ty khác nhau, trong những ứng dụng khác nhau, nên OpenGL hỗ trợ đồ hoạ mạnh, không những trong game mà kể cả các ứng dụng như CAD, hay mô phỏng.
Tuy nhiên điểm mạnh chủ yếu của OpenGL là nó quá đơn giản. Đây là một điểm rất “hấp dẫn” đối với những lập trình viên “mì ăn liền”, muốn tìm kiếm một thư viện nhanh, hiệu quả và dễ học. Viết code bằng OpenGL thường làm cho chương trình đơn giản, sáng sủa và dễ debug bởi lý do này. Ngoài ra, OpenGL còn che dấu toàn bộ quá trình rendering pipeline phức tạp của nó, do đó bạn chẳng cần quan tâm đến cấu trúc hay chi tiết của nó như Direct3D. Khởi tạo OpenGL chỉ cần khoảng 20 dòng code, thay vì vài trăm như Direct3D. Vả lại một số thư viện cộng thêm như AUX hay GLUT còn làm việc này giùm bạn. Chỉ một hàm, thế là OpenGL khởi tạo xong!!!
Thế nhưng cũng như Direct3D, điểm yếu của OpenGL nằm ngay ở các điểm mạnh trên. Việc các hàm OpenGL không đi sâu vào chi tiết giúp ta đỡ phải quan tâm đến “mấy cái không đâu”, tuy nhiên nếu khi cần đến “mấy cái không đâu” này thì mới thực sự là ác mộng. Bạn không thể can thiệp vào rendering pipeline của OpenGL đơn giản bởi vì nó không cho phép. Điều này làm cho một số hiệu ứng trở nên khó xử lý với OpenGL, trong khi Direct3D cho phép thực hiện dễ dàng, ví dụ như customize blending.
OpenGL dùng cầu nối là các extensions, tuy nhiên do các thành viên của ARB có nguồn gốc từ nhiều công ty khác nhau, vì vậy họ thường không đưa ra được một chuẩn chung (“lắm thầy thì thối ma” thôi). nVidia, ATI cứ đưa ra chuẩn riêng của mình, cùng một hàm Pixel Shaders, nVidia đưa ra một hàm, ATI đưa ra một hàm, tên khác nhau, nhận biến khác nhau, và quan trọng là card hãng nào chỉ support extensions của hãng nấy. Vậy là nếu muốn sử dụng chức năng này, ta phải test xem card của máy user là card gì rồi chạy code tương ứng, thật là rắc rối cuộc đời. Chính vì lý do này mà chỉ một số đại gia game gạo cội mới dám xử dụng các chức năng chết người này. Điều này cũng làm cho việc sử dụng các extensions không được phổ biến lắm, ngoại trừ các nhà phát triển gạo cội như id Software hoặc các chương trình test card mà thôi.
Tuy tên hàm của OpenGL được đặt khá thân thiện, tuy nhiên điều này cũng gây ra ít nhiều phiền toái. Cùng một hàm khai báo màu cho vertex đang xài mà có đến glColor3f, glColor3ub, glColor3b, glColor3fv, glColor4f,… Tổng cộng có đến 32(!!!) hàm glColor… Thật đau khổ vì nếu bạn muốn sử dụng dữ liệu vào kiểu gì, bạn phải nhớ hàm tương ứng. Tuy nhiên điều này cũng có thể giải quyết được bằng cách overload các hàm cùng tên, việc mà hầu hết các ngôn ngữ OOP đều support. Một điều cần quan tâm nữa là các hàm của OpenGL tuy dễ sử dụng nhưng để hiểu rõ các đối số vào thì không dễ dàng tí nào, bạn cần phải hiểu chúng thật rõ mới có thể tạo được hiệu ứng như mong đợi. Chẳng hạn blending có khoảng 10 tham số phối hợp đôi. Nếu bạn không hiểu rõ cách làm việc của cơ chế blend và các tham số của OpenGL thì xác suất việc chọn đúng 1 trong 90 tổ hợp này để tạo thành hiệu ứng đúng có thể so sánh với xác suất bạn đánh trúng đề!!!
Tuy đã già, nhưng OpenGL vẫn chưa có vẻ sẽ chịu chết, ít nhất là trong vòng năm tới. 3D Lads và các thành viên ARB đang xúc tiến để cho ra đời OpenGL 2.0, một phiên bản mang một khuôn mặt hoàn toàn mới. Theo lời các nhà phát triển, phiên bản này sẽ cho phép người sử dụng can thiệp vào quá trình rendering pipeline dễ dàng bằng cách thay đổi hay tự viết code mới. Và quan trọng hơn, các extensions sẽ dùng một chuẩn chung thống nhất. Vậy nếu bạn chọn OpenGL, bạn hoàn toàn có thể tin tưởng vào nó thông qua quá khứ huy hoàng của nó và một tương lai phía trước.
Khi lập trình game, ý tôi muốn nói là lập trình game nghiêm túc theo đúng nghĩa của nó, tức là không phải dùng phần mềm tạo game hay dùng một engine nào đó có sẵn, người lập trình chắc chắn phải "đụng đến" vấn đề lập trình đồ hoạ. Khi đó họ sẽ phải chọn lựa giữa 2 bộ thư viện API đồ họa phổ biến nhất hiện nay. Đó là OpenGL và Direct3D. Sử dụng thư viện nào, thư viện nào tốt hơn trong hai bộ thư viện này đã và đang luôn luôn là câu hỏi gây nên vô số tranh cãi. Thông thường các lập trình viên thường chia thành hai trường phái đối lập hẳn nhau. Một cho rằng DirectX là con đường duy nhất dẫn đến La Mã và còn lại thì ngã về OpenGL. Trong bài viết này, mục đích của tôi là phân tích một số mặt mạnh và yếu của hai bộ thư viện trên thông qua một số kinh nghiệm (ít) và thông tin thu thập được trong thời gian qua (của người khác-nhiều). Tôi cũng không có ý định đưa chi tiết cấu trúc cũng như hướng dẫn cách sử dụng chúng trong bài viết này. Tuy nhiên các bạn có thể tìm thấy vô số các bài viết, hướng dẫn và sách vở về chúng trên mạng nếu muốn. Links về Direct3D và OpenGL đã rất nhiều lần được CrazyBabe và tôi đưa lên diễn đàn này.
Chú thích thêm: Tôi là một thành viên của trường phái OpenGL. Tôi bắt đầu nghiên cứu OpenGL trong khoảng 2 năm nay và chỉ biết rất ít về Direct3D, do đó các kiến thức và hiểu biết của tôi về Direct3D chỉ có hạn và vì vậy các nhận xét về Direct3D phần lớn chỉ các thông tin thu thập từ sách vở. Vậy nếu bạn thấy rằng tôi hơi ngả về OpenGL thì cũng xin châm chước cho và đừng làm bài viết này thành ra một cuộc tranh cãi nhé. Cám ơn rất nhiều.
Direct3D
Trong một thời gian rất dài, Direct3D không được xem không thể là đối thủ của OpenGL trong mặt trận game. Tuy nhiên gần đây, sau hàng loạt cố gắng và cải tiến đáng kể của Microsoft, Direct3D đã từng bước giàng được một thị phần đáng kể trong thế giới phát triển game hiện nay, nhất là sau sự ra đời của DirectX7, “kẻ huỷ diệt” của OpenGL. Trái hẳn với các phiên bản Direct3D đầy bọ trước, đồ hoạ trong DirectX7 được tách thành 2 phần riêng biệt: DirectDraw và Direct3D, xử lý các hình ảnh 2D và 3D, theo thứ tự đó. Cùng với hàng loạt cải tiến mới và hiệu quả, DirectX từng bước trở thành một chuẩn mực và lựa chọn đầu tiên của các lập trình viên game trên nền Windows.
Direct3D được xây dựng trên nền kiến trúc COM. Chắc hẳn các bạn đã biết đến khái niệm này. Nói nôm na, cho dễ hiểu, Direct3D làm việc bằng các class, tức hướng đối tượng. Với một số lượng class “khấm khá”, Direct3D hỗ trợ hầu hết các công việc mà một lập trình viên cần, ngoài ra nó còn đặt ra và hỗ trợ các định dạng của riêng nó như mô hình mesh (.X) và texture (.dds). Điều này đặt biệt “hay ho”. Một điều đáng lưu ý nữa là Direct3D hỗ trợ chi tiết toàn bộ rendering pipeline của nó. Bạn có thể can thiệp ngay cả vào một số phần của rendering pipeline.
Phiên bản đang được sử dụng phổ biến hiện nay của dòng DirectX, DirectX8, đã bổ sung vào hai thành phần đang được xem là “mode” trong giới đồ hoạ 3D. Đó là Programmable Pixel và Vertex Shaders. Đương nhiên khó mà giải thích được hai khái niệm trên một cách ngắn gọn, tuy nhiên có thể nói ngắn gọn là với hai công cụ trên, bạn có thể sửa đổi một số phần trong rendering pipeline của Direct3D bằng một số mã lệnh gần giống assembly. Nghe thì có vẻ không ghê gớm gì, nhưng nếu bạn đã từng bị kẹt như tôi trong khi đang làm một số hiệu ứng trong OpenGL thì việc can thiệp được “một tí gì” vào rendering pipeline quả là một phép thần kỳ…. Tuy nhiên, cũng phải nói thêm rằng, không phải card đồ hoạ nào cũng support hai công cụ trên đâu. Ít nhất thì cũng phải card kha khá như ATI 8500, GF3, GF4Ti,… trở lên. Đáng buồn thay.
Direct3D trong phiên bản DX8 bổ sung hàng tá hỗ trợ trong việc tạo hiệu ứng, điều này đã qua mặt OpenGL, vốn được cập nhật khá chậm chạp. Phiên bản DX9 hiện nay hỗ trợ vô số hiệu ứng. Có thể nói, với Pixel Shaders và Vertex Shaders, tất cả những gì bạn cần hiện nay là một card đồ họa tốt. Thế thôi, sau đó thì… tha hồ tưởng tượng!!!
Microsoft là một đại gia. Điều đó thì ai cũng biết. Họ hẳn là có liên hệ chặt chẽ với các nhóm phát triển phần cứng (như nVidia hay ATI,… ), vì vậy về chuyện ứng dụng phần cứng tối ưu hay tận dụng sức mạnh của các card đồ hoạ mới nhất thì bạn khỏi phải lo. Phần mềm đi trước phần cứng (như trường hợp DX9 ra đời cả mấy tháng nay mà hiện nay vẫn chưa có game nào tận dụng hết sức mạnh của nó) là chuyện bình thường.
Tuy nhiên, Direct3D không phải là không có điểm yếu. Người ta thường nói, “lắm tài thì nhiều tật”. Điểm mạnh của Direct3D cũng là điểm yếu của nó.
Direct3D quá chi tiết, mà chi tiết quá thì thế nào cũng phức tạp. Điểm yếu đầu tiên của Direct3D là quá phức tạp. Bạn phải mất khoảng từ 200 dòng code để có thể bắt tay vào vẽ bằng Direct3D. Đối với các bạn mới bắt đầu học thì chuyện này cũng tương tự như chuyển từ Turbo C sang Visual C++… Tuy nhiên, điều đó cũng chẳng đáng gì so với việc bạn phải có một số kiến thức về đồ hoạ máy tính lý thuyết (lý thuyết nhá, ý tôi muốn nói là ma trận, vector, nội suy,… những thứ khô khan đối với dân tin) bởi Direct3D quá chi tiết, và bạn cần phải hiểu rõ ràng tất cả nhưng hàm và phương thức chi tiết này. Điều này dẫn đến code của bạn sẽ rất dễ bị bọ chui vào nếu không cẩn thận.
Direct3D do Microsoft phát triển. Và vì bạn đã biết Microsoft chẳng ưa gì Linux hay Unix, (Bill Gate thậm chí còn muốn chúng “chết” nhanh nữa là khác), vì vậy Direct3D chỉ chạy trên Windows, và chỉ Windows mà thôi. Đừng hòng chú chim cánh cụt mó tay cùi vào nhá. Bạn chọn Direct3D, thế thì phải chắc chắn là game bạn viết chỉ chạy trên Windows thôi nhá. Đừng mong gì recompile lại trên Linux hay Unix.
Direct3D hỗ trợ game tốt, điều này thì ngay cả dân trung thành hâm mộ OpenGL từ bao nhiêu năm qua dù si mê cuồng vọng OpenGL đến mấy thì cũng phải công nhận. Tuy nhiên, trong mặt trận khác như đồ hoạ kỹ thuật, CAD, hay ứng dụng đòi hỏi 3D thì Direct3D chưa hề có chỗ chen chân vào.
Một điểm nữa làm cho Direct3D thêm phần rắc rối cuộc đời là do sự cống hiến nhiệt tình của Microsoft. Cứ mỗi phiên bản DirectX khác nhau là bác Bill nhà ta xây dựng lại, cập nhật thêm tùm lum nào là đối tượng mới, nào là hàm mới. Chuyện này nói ra thì cũng tốt bởi vì cuối cùng là lập trình viên được lợi thôi, tuy nhiên làm như thế thì các chương trình viết dễ bị không tương thích lắm. Ví dụ như bạn viết game trên nền DirectX7, đến khi chạy trên nền DirectX9 sẽ bị không tương thích nếu như lỡ dại xài một số hàm mà DirectX9 không còn hỗ trợ (như ảnh stereo chẳng hạn), lúc đó thì khóc dở mếu dở. Microsoft đã thông báo là phiên bản tiếp theo DirectX X (!!!,đừng nhầm với *** nhá) ít nhất sẽ không ra mắt cho tới giữa năm sau do DirectX9 hiện đã quá đủ đối với phần cứng hiện nay. Hy vọng họ không “đẻ” ra thêm cái gì mới, DirectDraw, Direct3D và DirectSurface hiện nay đã đủ phức tạp quá rồi còn gì.
Tương lai của Direct3D vẫn còn nằm ở phía trước và chắc chắn rằng (hu hu!!!) nó sẽ trở thành một chuẩn mực của tất cả game chạy trên nền Windows. Nếu bạn chọn Direct3D, bạn đã mua được một chiếc vé bay vào tương lai của anh Bill rồi đấy.
OpenGL
OpenGL đã được ra đời và phát triển hơn 10 năm nay. Với một thời gian dài như vậy, rõ ràng nó đã chứng tỏ được sự ổn định và hấp dẫn của mình rồi, bởi không ai lại đi xài một bộ thư viện quá già nua như thế mà không có lý do chứ? OpenGL được phát triển bởi SGI từ 10 năm trước, với mục đích là tạo nên một bộ thư viện đồ hoạ ổn định lâu dài và hướng đến tương lai. Xin nói rõ là: tương lai của 10 năm trước, tức OpenGL nhắm vào các hệ thống đồ hoạ lớn và đắt tiền như các máy trạm SGI chuyên dùng vào đồ họa. Trong 10 năm đó, OpenGL phát triển rất chậm (cho đến hiện nay mới chỉ là version 1.4), trong khi tốc độ của các card đồ hoạ bình dân (là loại card mà chúng ta hiện đang sử dụng) đã vượt xa mức tưởng tượng của các nhà phát triển OpenGL 10 năm trước. Với một thực tế như thế, có thể nói thời hoàng kim của OpenGL đã đến và trôi qua từ lâu.
Thế nhưng, không phải vì thế mà nói OpenGL không đi kịp thời đại. OpenGL vẫn gắn bó mật thiết với sự phát triển của phần cứng thông qua ARB (Architecural Review Board). Đây là một hội đồng bao gồm các công ty và nhà phát triển phần cứng có liên quan đến đồ hoạ, có thể kể như 3D Lads, SGI, nVidia, ATI, Microsoft, id Software hay Intel nữa. Nhóm này chuyên đưa ra các chuẩn và mở rộng (extensions) của OpenGL để bộ thư viện này không bị lỗi thời với nhịp đua của thời đại. Có thể nói là các extensions là cầu nối để OpenGL có thể bắt kịp với hiện tại, là những bộ chip xử lý đồ hoạ mới được cập nhật với bao nhiêu chức năng cao cấp, điều mà những người phát triển OpenGL từ thuở sơ khai đã chưa hề tưởng tượng được.
OpenGL được phát triển từ lâu, vào thời mà OOP vẫn chưa được thịnh hành, do đó nó đơn thuần chỉ là một bộ thư viện API bao gồm các nhiều hàm đồ hoạ. OpenGL có khoảng 200 hàm đồ hoạ chuẩn, và khoảng chừng đó số lượng các hàm extensions. Con số này trông có vẻ nhiều, tuy nhiên không thấm vào đâu so với DirectX. Các hàm của OpenGL chỉ thuần tuý là hàm, tức là không dùng class, tuy nhiên bạn có thể tạo class của bạn trên cơ sở các hàm này để tạo nên ứng dụng OpenGL bằng OOP của mình. Sử dụng OpenGL như thế nào hoàn toàn tuỳ thuộc vào bạn.
Các hàm và khai báo của OpenGL đặc biệt thân thiện với người sử dụng. Các tên hàm như glColor3f hoàn toàn có thể nói rõ bản chất hoạt động của hàm. “gl” chỉ hàm của OpenGL, “Color” chỉ rõ đây là hàm khai báo màu sắc, “3” chỉ số thành phần màu sắc (R, G, B), trong khi “f” chỉ loại kiểu dữ liệu đưa vào là float. Việc sử dụng ít hàm và tên hàm thân thiện đã làm cho việc lập trình bằng OpenGL đơn giản, ngắn gọn và dễ debug hơn nhiều so với Direct3D.
OpenGL có nhiều điểm mạnh vượt trội. Điều đầu tiên có thể nói về OpenGL là tính tương tích của bộ thư viện này rất cao. Bạn có thể sử dụng OpenGL trong hầu hết các hệ khác nhau như Linux, Unix và dĩ nhiên cả Windows. Bất cứ trình dịch bằng ngôn ngữ lập trình nào cũng có thể dùng OpenGL bởi nó được cung cấp dưới dạng API trong các thư viện động dll, và điều quan trọng nhất là các thư viện động này đã được tích hợp sẵn vào Windows. Bạn không cần cài đặt OpenGL, chỉ cần include file header của OpenGL vào và voila, viết code thoải mái.
OpenGL với sự giúp đỡ của ARB đã bắt kịp với nhịp tiến của các card đồ hoạ mới nhất hiện nay. OpenGL support tất cả những gì Direct3D hỗ trợ, bao gồm cả Pixel Shaders và Vertex Shaders, tuy nhiên vẫn cũng chỉ các card như GF3, GF4Ti hay ATI 8500 mới có thể dùng được các chức năng này (buồn 5 phút cho những kẻ sử dụng GF4MX như tôi). Bởi vì ARB bao gồm nhiều công ty khác nhau, trong những ứng dụng khác nhau, nên OpenGL hỗ trợ đồ hoạ mạnh, không những trong game mà kể cả các ứng dụng như CAD, hay mô phỏng.
Tuy nhiên điểm mạnh chủ yếu của OpenGL là nó quá đơn giản. Đây là một điểm rất “hấp dẫn” đối với những lập trình viên “mì ăn liền”, muốn tìm kiếm một thư viện nhanh, hiệu quả và dễ học. Viết code bằng OpenGL thường làm cho chương trình đơn giản, sáng sủa và dễ debug bởi lý do này. Ngoài ra, OpenGL còn che dấu toàn bộ quá trình rendering pipeline phức tạp của nó, do đó bạn chẳng cần quan tâm đến cấu trúc hay chi tiết của nó như Direct3D. Khởi tạo OpenGL chỉ cần khoảng 20 dòng code, thay vì vài trăm như Direct3D. Vả lại một số thư viện cộng thêm như AUX hay GLUT còn làm việc này giùm bạn. Chỉ một hàm, thế là OpenGL khởi tạo xong!!!
Thế nhưng cũng như Direct3D, điểm yếu của OpenGL nằm ngay ở các điểm mạnh trên. Việc các hàm OpenGL không đi sâu vào chi tiết giúp ta đỡ phải quan tâm đến “mấy cái không đâu”, tuy nhiên nếu khi cần đến “mấy cái không đâu” này thì mới thực sự là ác mộng. Bạn không thể can thiệp vào rendering pipeline của OpenGL đơn giản bởi vì nó không cho phép. Điều này làm cho một số hiệu ứng trở nên khó xử lý với OpenGL, trong khi Direct3D cho phép thực hiện dễ dàng, ví dụ như customize blending.
OpenGL dùng cầu nối là các extensions, tuy nhiên do các thành viên của ARB có nguồn gốc từ nhiều công ty khác nhau, vì vậy họ thường không đưa ra được một chuẩn chung (“lắm thầy thì thối ma” thôi). nVidia, ATI cứ đưa ra chuẩn riêng của mình, cùng một hàm Pixel Shaders, nVidia đưa ra một hàm, ATI đưa ra một hàm, tên khác nhau, nhận biến khác nhau, và quan trọng là card hãng nào chỉ support extensions của hãng nấy. Vậy là nếu muốn sử dụng chức năng này, ta phải test xem card của máy user là card gì rồi chạy code tương ứng, thật là rắc rối cuộc đời. Chính vì lý do này mà chỉ một số đại gia game gạo cội mới dám xử dụng các chức năng chết người này. Điều này cũng làm cho việc sử dụng các extensions không được phổ biến lắm, ngoại trừ các nhà phát triển gạo cội như id Software hoặc các chương trình test card mà thôi.
Tuy tên hàm của OpenGL được đặt khá thân thiện, tuy nhiên điều này cũng gây ra ít nhiều phiền toái. Cùng một hàm khai báo màu cho vertex đang xài mà có đến glColor3f, glColor3ub, glColor3b, glColor3fv, glColor4f,… Tổng cộng có đến 32(!!!) hàm glColor… Thật đau khổ vì nếu bạn muốn sử dụng dữ liệu vào kiểu gì, bạn phải nhớ hàm tương ứng. Tuy nhiên điều này cũng có thể giải quyết được bằng cách overload các hàm cùng tên, việc mà hầu hết các ngôn ngữ OOP đều support. Một điều cần quan tâm nữa là các hàm của OpenGL tuy dễ sử dụng nhưng để hiểu rõ các đối số vào thì không dễ dàng tí nào, bạn cần phải hiểu chúng thật rõ mới có thể tạo được hiệu ứng như mong đợi. Chẳng hạn blending có khoảng 10 tham số phối hợp đôi. Nếu bạn không hiểu rõ cách làm việc của cơ chế blend và các tham số của OpenGL thì xác suất việc chọn đúng 1 trong 90 tổ hợp này để tạo thành hiệu ứng đúng có thể so sánh với xác suất bạn đánh trúng đề!!!
Tuy đã già, nhưng OpenGL vẫn chưa có vẻ sẽ chịu chết, ít nhất là trong vòng năm tới. 3D Lads và các thành viên ARB đang xúc tiến để cho ra đời OpenGL 2.0, một phiên bản mang một khuôn mặt hoàn toàn mới. Theo lời các nhà phát triển, phiên bản này sẽ cho phép người sử dụng can thiệp vào quá trình rendering pipeline dễ dàng bằng cách thay đổi hay tự viết code mới. Và quan trọng hơn, các extensions sẽ dùng một chuẩn chung thống nhất. Vậy nếu bạn chọn OpenGL, bạn hoàn toàn có thể tin tưởng vào nó thông qua quá khứ huy hoàng của nó và một tương lai phía trước.