OpenGL, SFML và SDL có lợi thế gì so với kết xuất phần mềm?


24

Tôi bắt đầu xem luồng Handmade Hero , nơi Casey Muratori tạo ra một công cụ trò chơi mà không cần sử dụng các khung công tác hay như vậy. Hôm qua tôi đã đến phần mà anh ấy cho thấy một hình ảnh được vẽ trên màn hình như thế nào. Theo như tôi hiểu thì anh ta chỉ phân bổ một số bộ nhớ lớn bằng kích thước màn hình mà anh ta muốn vẽ. Và sau đó anh ta tạo ra một bitmap mà anh ta chuyển đến bộ nhớ đệm mà anh ta đã phân bổ và vẽ nó lên màn hình bằng một hàm os cụ thể.

Điều này có vẻ khá thẳng về phía trước. Tôi đã sử dụng GameMaker, đổi thành Love2D, làm việc một chút với Sprite Kit nhưng tôi luôn tự hỏi điều gì đang thực sự xảy ra bên dưới lớp đôi khi khó hiểu này.

Vì vậy, tại sao thậm chí còn bận tâm sử dụng các thư viện đồ họa (OpenGL, SFML, SDL, ') khi tất cả những gì bạn phải làm chỉ đơn giản là phân bổ một số bộ đệm, chuyển một bitmap và vẽ nó ra màn hình?

Nếu sau đó bạn muốn vẽ những thứ khác biệt lên màn hình của mình, bạn chỉ cần viết chúng vào bitmap của mình, sau đó được chuyển vào bộ đệm. Tôi còn khá mới với lập trình, nhưng điều này có vẻ khá đơn giản với tôi. Hãy sửa lại cho tôi nếu tôi sai.


11
sau đó trong loạt phim của anh ấy (khoảng tập 220) anh ấy sẽ sử dụng opengl. Lý do anh ấy làm điều đó là tốc độ.
quái vật ratchet

5
Bí quyết là xác định những gì để vẽ lên màn hình. Tất cả các kết cấu / công cụ tô bóng GPU, hình tam giác, hình chiếu của camera, v.v ... cần phải được thực hiện trước tiên để quyết định màu sắc của mỗi pixel. Đẩy màu pixel vào màn hình là phần dễ dàng.
dùng14146

2
Đối với bản ghi, SDL và OpenGL không loại trừ lẫn nhau. SDL là một "lớp trừu tượng phần cứng" cũng xử lý các cửa sổ, sự kiện và đầu vào thay vì chỉ là một thư viện đồ họa. SDL cũng có hỗ trợ được sử dụng cùng với OpenGL để SDL có thể thực hiện tất cả các công cụ phi đồ họa trong khi OpenGL xử lý đồ họa. Cũng lưu ý rằng phần lớn OpenGL hoạt động trực tiếp với GPU trong khi SDL có thể hoặc không tùy thuộc vào phiên bản và hệ thống được biên dịch.
Pharap

SFML sử dụng OpenGL để kết xuất, vì vậy thực sự tất cả SFML đều cung cấp giao diện đơn giản hơn để sử dụng OpenGL.
Bắp ngô

2
Techcnailyl những gì Casey đang làm vẫn đang sử dụng một thư viện đồ họa. Thư viện được gọi là GDI và mặc dù nó là một phần của API chính của HĐH, nhưng về mặt kỹ thuật, đây vẫn là một thư viện đồ họa.
Pharap

Câu trả lời:


41

Nó không chỉ là về tốc độ thực hiện, mà còn về sự đơn giản. Mặc dù kết xuất phần mềm được sử dụng trong ví dụ này sẽ chậm hơn rất nhiều so với sử dụng tăng tốc phần cứng (ví dụ như GPU), vẽ một vài bitmap trên màn hình là một công việc tầm thường mà bạn sẽ không nhận thấy hiệu suất giảm.

Tuy nhiên, hoạt động cấp thấp như rasterisation tam giác, sắp xếp độ sâu và tương tự là những khái niệm được hiểu rõ mà GPU có thể xử lý ngầm với một vài lệnh. Thực hiện lại những người trong chế độ phần mềm về cơ bản là phát minh lại bánh xe. Điều này tốt nếu bạn muốn có được sự hiểu biết ở mức độ thấp về cách thực hiện kết xuất, bản thân tôi đã viết một trình kết xuất phần mềm 3D chỉ để khám phá nó một chút, nhưng trong hầu hết các trường hợp, thật lãng phí thời gian khi OpenGL có thể thực hiện nhanh hơn cái hộp.

Ví dụ bạn đã đưa ra âm thanh cực kỳ cơ bản, chỉ cần vẽ một hình ảnh duy nhất trên màn hình, do đó việc thực hiện rất dễ dàng. Khi bạn bắt đầu phân lớp theo độ phức tạp, bạn sẽ thấy nó trở nên ngày càng phức tạp để có được mọi thứ hiển thị chính xác. Những thứ mọi người phải làm lại trong những ngày Quake kết xuất phần mềm 3D là điên rồ, mặc dù tôi đánh giá cao việc bạn sẽ không đi quá xa (chưa).


12
OpenGL biết các thuật ngữ như điểm, đường và hình tam giác. Hầu hết thời gian bạn sẽ làm việc với hình tam giác. Để tìm hiểu cách làm việc với OpenGL, tôi có thể giới thiệu opengl-tutorial.org . Để tìm hiểu những gì OpenGL làm trong chương trình này, hãy xem wiki chính thức: opengl.org/wiki/Rendering_Pipeline_Overview
tkausl

1
Tôi đã lên +1 nhưng tôi không thích chút nào về việc "phát minh lại bánh xe" bởi vì tôi cảm thấy nó mang lại ấn tượng sai về mặt lịch sử của máy tính. Kết xuất bitmap xuất hiện đầu tiên, do đó OpenGL là một trong những "phát minh lại bánh xe". Tuy nhiên, họ có hai lý do chính đáng để làm như vậy: 1) Tiêu chuẩn hóa và 2) Tăng tốc GPU. Phát minh lại bánh xe không phải lúc nào cũng là một điều tồi tệ nếu phiên bản mới là một sự cải tiến (tức là bánh xe có lốp so với bánh xe bằng gỗ). Điểm mấu chốt ở đây không phải là phần mềm kết xuất đang phát minh lại bánh xe, mà nó phải kém hơn kết xuất GPU.
Pharap

4
@Pharap ngoại trừ bây giờ , viết một trình kết xuất phần mềm hoàn toàn đang phát minh lại bánh xe, bất kể đó có phải là lịch sử hay không.
porglezomp

1
Đây chỉ là một nửa câu trả lời. Câu trả lời tiếp theo là nửa kia, nhưng một câu trả lời hoàn chỉnh (bao gồm một chút giải thích về sự khác biệt giữa OpenGL và những thứ khác mà anh ấy đề cập) sẽ là câu trả lời thích hợp cho câu hỏi này.
Jasper

1
@ user148013 "Opengl có biết các thuật ngữ như điểm, đường thẳng, tam giác không?" OpenGL hiện đại giao dịch độc quyền với các nguyên thủy này. Bạn không thể rasterize bất cứ điều gì trừ chúng.
Nax 'vi-vim-nvim'

25

Câu hỏi của tôi là: tại sao thậm chí bận tâm sử dụng một cái gì đó như open gl, sfml, sdl khi tất cả những gì bạn phải làm chỉ đơn giản là phân bổ một số bộ đệm, truyền một bitmap và vẽ nó lên màn hình?

Ngắn: Bởi vì nó nhanh (OpenGL, DirectX).

Dài:

Bạn có thể nghĩ rằng bạn có thể tự làm tất cả điều này. Vẽ pixel vào màn hình. Bạn có thể viết một thư viện nhỏ để vẽ các hình dạng, như hình tứ giác hoặc hình tam giác. Điều này sẽ làm việc, tất nhiên. Có rất nhiều thư viện ngoài kia để làm chính xác điều này. Một số trong số họ thậm chí còn triển khai OpenGL-spec (vì vậy chúng giống như một phần mềm dành cho opengl) sẽ làm chính xác những gì Casey Muratori làm. Họ tính toán mọi thứ ở phía phần mềm, đặt các pixel ở phía phần mềm và ghi kết quả lên màn hình.

Tuy nhiên điều này là chậm . CPU cuối cùng sẽ thực hiện tất cả những điều này đã không được thực hiện cho kịch bản này. Đó là những gì GPU dành cho. Những gì OpenGL làm (tất nhiên trừ khi đó là triển khai phần mềm) sẽ lấy mọi thứ bạn bảo nó làm và đẩy tất cả dữ liệu, tất cả các cuộc gọi rút thăm, gần như mọi thứ vào card đồ họa và bảo GPU làm việc. GPU được làm riêng cho loại công việc này. Nhân các số dấu phẩy động (Đó là những gì bạn làm rất nhiều khi vẽ cảnh 3D) và thực hiện các shader. Và điều này song song. Để giúp bạn hiểu được GPU nhanh như thế nào, hãy nghĩ về một cảnh đơn giản ở chế độ 3D ở chế độ toàn màn hình với 1920x1080 pixel. Chúng được nhân lên, 2.073.600 pixel để vẽ. Đối với mỗi mộtpixel, GPU sẽ chạy shader mảnh ít nhất một lần , hầu hết nhiều lần hơn một lần. Bây giờ, giả sử chúng ta chạy ở tốc độ 60 khung hình mỗi giây. Điều này có nghĩa, GPU chạy shader mảnh vỡ 2.073.600 * 60 = 124.416.000 lần mỗi giây . Bạn có nghĩ rằng bạn có thể làm một cái gì đó như thế này trên CPU của bạn? (Đó là một lời giải thích khá đơn giản, có rất nhiều điều cần xem xét như bạn đã rút bao nhiêu pixel bởi các đối tượng gần hơn, bao nhiêu MSAA bạn sử dụng, v.v., tuy nhiên, 124,416.000 lần mỗi giây có lẽ là mức thấp nhất bạn có thể nhận được, và bạn Sẽ dễ dàng có nhiều hơn 60 khung hình / giây với một cảnh đơn giản)

Đó là những gì OpenGL và Direct3D làm, cho những công cụ nào thấy @Uri Popovs trả lời.


8
Anh ấy đang tạo ra một trò chơi 2D, đó là một chủ đề khác như 3D. Và khi tôi nói chậm, điều đó không nhất thiết có nghĩa là nó có ít hơn 60 khung hình / giây nhưng điều đó có nghĩa là card đồ họa sẽ thực hiện công việc tương tự trong một phần nhỏ thời gian CPU cần, ít nhất là khi đến không gian 3D.
tkausl

4
Chà, lý do GPU tốt hơn là vì chúng được thiết lập để song song với các yêu cầu đổ bóng.
quái vật ratchet

4
@ user148013 Từ những gì tôi thấy từ anh chàng này, tôi sẽ nói anh ta hoàn toàn trái ngược với "rất khôn ngoan".
Bartek Banachewicz

4
Không chỉ là nó hiển thị chậm hơn (trình kết xuất phần mềm của Casey nhanh đến mức đáng ngạc nhiên). Đó cũng là rất nhiều dữ liệu để tiếp tục đẩy từ RAM chung sang RAM video. Đẩy một bitmap khổng lồ vào card màn hình, tùy thuộc vào loại xe buýt, có thể mất một đoạn đáng kể thời gian khung hình. Sử dụng GPU, thỉnh thoảng bạn đẩy họa tiết và sử dụng chúng cho từng khung hình.
Adrian McCarthy

2
@ user148013 Có sự khác biệt giữa lập trình hào nhoáng và tốt. Chúng có thể chồng lên nhau, nhưng thường thì chúng bị xung đột. Tôi đã đặt "Tôi có thể kết xuất trong phần mềm [giống như MESA có thể ...]" dưới sự hào nhoáng và chắc chắn là không tốt .

11

Những gì anh ta làm được gọi là kết xuất phần mềm , những gì OpenGL làm được gọi là kết xuất GPU

Sự khác biệt giữa chúng là gì? Tốc độ và bộ nhớ.

Rasterization (điền vào các hình tam giác trên màn hình) mất một thời gian. Nếu bạn làm điều đó trên CPU, về cơ bản, bạn sẽ mất thời gian đó khỏi logic trò chơi, đặc biệt là nếu nó không được tối ưu hóa tốt.

Và không quan trọng, hình ảnh nhỏ đến mức nào, anh ta cần phân bổ lượng bộ nhớ nhất định cho nó. GPU có bộ nhớ video cho việc này.


Có thể kết xuất phần mềm trên OS X không? Bởi vì dường như mọi thứ liên quan đến đồ họa đã được OpenGl thực hiện ngay bây giờ Metal.
user148013

2
@ user148013 Bạn có một số hiểu lầm. OpenGL là một API đa nền tảng, vì vậy nó có thể chạy trên OS X, trên thực tế, nó có thể chạy trên mọi thứ với GPU "hiện đại" (bài 2000). Metal là một API riêng cho các thiết bị của Apple. Kết xuất phần mềm cũng là một điều riêng biệt với cả hai và vâng, nó cũng có thể được thực hiện trên OS X. Về cơ bản, nó chỉ là cài đặt pixel thủ công trên màn hình với CPU.
Bálint

Đó chính xác là lý do tại sao tôi hỏi vì theo như tôi biết thì việc kết xuất phần mềm không thể thực hiện được trên OS X. Ca cao tiếp cận với OpenGl, Quarz sử dụng OpenGl, Core Framework sử dụng OpenGl. Bây giờ tất cả họ sử dụng Metal như cách nhanh hơn. Nhưng tôi đã không tìm thấy một chức năng duy nhất thu hút bộ đệm vào màn hình mà không sử dụng GPU (OpenGl, Metal).
user148013

1
@ user148013 Bởi vì nó không dành riêng cho HĐH, cũng như triển khai. Giả sử bạn muốn triển khai nó trong java, vì đó là một lựa chọn nổi tiếng để phát triển đa nền tảng. Với java, trước tiên bạn có thể làm điều đó bằng cách tạo một cửa sổ (JFrame), sau đó thay vì vẽ thẳng lên nó, bạn vẽ lên một hình ảnh, sau đó bạn đặt hình ảnh này lên khung. Tuy nhiên, nó sẽ không biết các thuật ngữ "tam giác" hoặc "đường thẳng". Chỉ màu sắc. Bạn cần phải tự thực hiện điều đó bằng thuật toán rasterization. Đây là lý do tại sao chúng tôi thích OpenGL, nó nhanh hơn và dễ sử dụng hơn một chút. Về cơ bản, nó là một API rasterization.
Bálint

2
@ user148013 Tại sao họ không thể? Nếu họ có thể mở một cửa sổ và họ có thể vẽ 1 hình ảnh trên đó mà không cần API, thì họ có thể.
Bálint

8

Mặc dù câu trả lời từ những người khác là chính xác hơn bất kỳ câu trả lời nào tôi có thể đưa ra, tôi muốn chỉ ra sự hiểu lầm cơ bản về cách phát triển phần mềm hoạt động mà tôi nghĩ làm cơ sở cho câu hỏi của bạn. Mặc dù luôn có thể làm mọi thứ "một mình" mà không cần khung, và thường có lợi ích giáo dục lớn từ việc đó, nhưng thực tế không phải là cách phần mềm hiện đại được tạo ra.

Ai đó đã tạo ra phần cứng và ngôn ngữ máy chạy trên nó. Ai đó khác tạo các ngôn ngữ và trình biên dịch cấp cao hơn, trình điều khiển và hệ điều hành, thư viện đồ họa và bật và tắt. Chúng tôi mỗi người xây dựng dựa trên công việc của những người đi trước. Đó không chỉ là "được", đó là một yêu cầu.

Bạn đang vẽ đường của những gì "chấp nhận được" hay không tại một điểm tùy ý trong chuỗi công cụ. Bạn có thể dễ dàng nói "tại sao sử dụng C ++ khi bạn có thể làm điều tương tự trong lắp ráp?", Hoặc "tại sao phải dựa vào trình điều khiển bàn phím khi bạn có thể dễ dàng đọc các điện áp ra khỏi dây và tự tính toán?" Không có đủ thời gian trong ngày, hoặc nhiều năm trong cuộc đời để mọi người tự làm mọi thứ.

Điều này không chỉ áp dụng cho phát triển phần mềm, mà nói chung cho cuộc sống hiện đại. Bạn đã bao giờ nghe nói về anh chàng tự chế tạo máy nướng bánh mì, từ đầu chưa? http://www.thomasthwaites.com/the-toaster-project/ . Phải mất một thời gian thực sự dài và rất nhiều nỗ lực. Đối với một máy nướng bánh mì. Hãy thử tự mình xây dựng mọi thứ cần thiết để hiện thực hóa một trò chơi video từ ether!


2
Tôi nghĩ rằng đây là một câu trả lời tốt bởi vì nó nói tại sao sử dụng khung là tốt mà không coi thường ý tưởng phát minh lại bánh xe cho mục đích giáo dục.
Pharap

3

Động cơ làm nhiều hơn nữa chỉ cần vẽ một hình ảnh lên màn hình. Họ xử lý ánh sáng, bóng tối, đầu vào, phát hiện va chạm. Ngay cả phần kết xuất cũng phức tạp hơn nhiều so với việc đẩy bộ đệm lên màn hình. Đối với các cảnh 3d đặc biệt là bạn cần thực hiện nhiều phép tính trên dữ liệu phức tạp hơn nhiều so với bitmap. Hãy để tôi cung cấp cho bạn một sự tương tự với một chiếc xe hơi: Những gì bạn đang mô tả đơn giản là khí thải của chiếc xe. Bạn chỉ cần làm một đường ống với kích thước phù hợp và sau đó bạn đẩy khí từ đầu này sang đầu kia. Tuy nhiên điều này là xa những điều duy nhất xảy ra trong cơ chế của chiếc xe.


3

Các câu trả lời ở trên là tuyệt vời, nhưng không có câu trả lời nào thực sự vượt qua lý do quan trọng nhất là tại sao OpenGL và những thứ đó lại được ưa thích hơn. Lý do chính là để sử dụng phần cứng chuyên dụng được thiết kế đặc biệt để hoạt động với những thứ như hiển thị hàng triệu pixel trên màn hình, GPU .

Với kết xuất phần mềm, sử dụng CPU, trình kết xuất sẽ được lặp lại, từng cái một, trên tất cả các pixel trên bitmap và đưa ra các lệnh để hiển thị từng cái trên màn hình. Vì vậy, nếu bạn đang hiển thị hình ảnh có kích thước 1000x1000, 1.000.000 vòng lặp đó sẽ khiến CPU của bạn vượt qua. Chúng được thiết kế với sự kiểm soát trong tâm trí; rất nhiều nếu có điều kiện, nhảy từ bộ hướng dẫn này sang bộ hướng dẫn khác và một hướng kiểm soát chặt chẽ. Tuy nhiên, GPU được thiết kế với kiến ​​thức mà nó sẽ làm nhiều vòng lặp tương tự trên các pixel trên màn hình.GPU sẽ thực hiện một vòng lặp for với số lần lặp 1000000 và phân chia công việc theo số lượng lõi khổng lồ để mỗi lõi hoạt động ** song song và độc lập với nhau **. Vì vậy, không giống như CPU, mỗi khi GPU gặp phải một điều kiện khác, nó sẽ xử lý cả hai nhánh mã cho hai lõi của chính nó và THEN, cuối cùng, nó sẽ xem xét điều kiện mà nó đánh giá và loại bỏ kết quả của nhánh không cần thiết (đó là lý do tại sao rất nhiều điều kiện nếu khác trong trình tạo bóng GPU bị nhăn mặt; chúng luôn chịu trách nhiệm về sự lãng phí).

Vì vậy, có, GPU được xây dựng xung quanh song song . Điều đó làm cho việc làm việc trên pixel đối với chúng nhanh hơn nhiều so với CPU.


0

Xem Tôi có thực sự cần sử dụng API đồ họa không?

Chắc chắn, bạn có thể yêu cầu một bộ đệm, đặt một số bit trong đó và ghi nó vào màn hình. Đó thực chất là cách duy nhất để lập trình đồ họa trên PC cho đến khi có sẵn các trình tăng tốc đồ họa vào giữa những năm 90 từ 3DFX. Ngay cả trong Windows, DirectX đã được phát triển để cấp quyền truy cập trực tiếp vào bộ nhớ video.

Nhưng trên phần cứng không phải PC, máy chơi game chuyên dụng, luôn có các kỹ thuật để tăng tốc đồ họa bằng cách giảm tải công việc từ bộ xử lý. Ngay cả Atari 2600 cũng có "phần cứng", một phần vì nó không có đủ RAM cho bộ đệm khung.

Các máy chơi game sau này (giữa thập niên 80) đã được tối ưu hóa cho các trò chơi nền tảng. Một lần nữa, không có bộ đệm khung; thay vào đó, lập trình viên có thể chỉ định các ô của gạch :

Phần cứng đồ họa Genesis bao gồm 2 mặt phẳng có thể cuộn. Mỗi mặt phẳng được tạo thành từ gạch. Mỗi ô là một hình vuông 8 x 8 pixel với 4 bit cho mỗi pixel. Mỗi pixel do đó có thể có 16 màu. Mỗi ô có thể sử dụng 1 trong 4 bảng màu, vì vậy trên màn hình, bạn có thể nhận được 64 màu cùng một lúc, nhưng chỉ có 16 trong bất kỳ ô cụ thể nào. Gạch yêu cầu 32 byte. Có bộ nhớ đồ họa 64K. Điều này sẽ cho phép 2048 gạch duy nhất nếu bộ nhớ được sử dụng cho không có gì khác.


-2

Các CPU hiện đại đủ nhanh để thực hiện bất kỳ trò chơi 2d nào trong phần mềm, do đó, đối với đồ họa 2d, OpenGL / DirectX sẽ không có lợi thế nào, bên cạnh việc thêm một sự phụ thuộc khác và một lớp phức tạp vào dự án của bạn, ví dụ như đặt ma trận chiếu 3d để vẽ một bó các sprite và tải dữ liệu lên GPU.

OpenGL cũng sẽ buộc bạn đóng gói tất cả các họa tiết của bạn bên trong kết cấu 512x512 (một tạo tác của các bảng điều khiển cũ, như PSX, đóng gói đồ họa vào các trang bộ nhớ video), yêu cầu bạn phải viết mã đóng gói sprite khá phức tạp.

Mặt khác, nếu bạn đang thực hiện 3d, hiển thị hàng triệu hình tam giác với bóng mờ phức tạp, thì GPU là không thể tránh khỏi. Trước đây, phiên bản Direct3d đơn giản hơn 2d, được gọi là DirectDraw, GPU đã tăng tốc bản vẽ sprite, nhưng bây giờ Microsoft không còn hỗ trợ nó nữa, có thể vì CPU đủ nhanh để thực hiện 2d mà không cần tăng tốc, nếu bạn không quan tâm đến việc tiết kiệm năng lượng .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.