OpenGL、SFML、SDLには、ソフトウェアレンダリングと比べてどのような利点がありますか?


24

フレームワークなどを使用せずにCasey Muratoriがゲームエンジンを作成するHandmade Heroストリームを見始めました。昨日、私は彼が画面に画像が描かれる方法を示した部分に着きました。私が理解した限り、彼は描画したい画面のサイズと同じ大きさのメモリを割り当てました。そして、彼はビットマップを作成し、それを割り当てたバッファメモリに渡し、OS固有の関数を使用して画面に描画しました。

これは非常に簡単です。GameMakerを使用し、Love2Dに変更し、Sprite Kitで少し作業しましたが、この時々混乱するレイヤーの下で実際に何が起こっているのか常に疑問に思っていました。

それを考えると、単にバッファを割り当て、ビットマップを渡して画面に描画するだけでよいのに、なぜグラフィックライブラリ(OpenGL、SFML、SDLなど)を使用する必要があるのでしょうか。

その後、画面に明確なものを描画したい場合は、ビットマップに書き込むだけで、バッファに渡されます。私はプログラミングを始めたばかりですが、これは非常に簡単に思えます。私が間違っている場合は修正してください。


11
後のシリーズ(エピソード220前後)では、openglを使用します。彼がそうする理由はスピードです。
ラチェットフリーク

5
トリックは、画面にを描画するを決定することです。GPUのテクスチャ/シェーディング、三角形、カメラの投影などすべてを最初に実行して、各ピクセルの色を決定する必要があります。ピクセルの色を画面にプッシュするのは簡単です。
user14146

2
レコードに関しては、SDLとOpenGLは相互に排他的ではありません。SDLは、単なるグラフィックスライブラリではなく、ウィンドウ、イベント、および入力も処理する「ハードウェアアブストラクションレイヤー」です。SDLは、OpenGLと組み合わせて使用​​することもサポートしているため、OpenGLがグラフィックスを処理する間、SDLはすべての非グラフィックス処理を実行できます。また、ほとんどの場合、OpenGLはGPUで直接動作しますが、SDLはコンパイル対象のバージョンとシステムに依存する場合としない場合があります。
ファラプ

SFMLはレンダリングにOpenGLを使用するため、実際にSFMLが実行するのは、OpenGLを使用するためのよりシンプルなインターフェイスを提供することだけです。
トウモロコシ茎

2
Techcnailylは、Caseyがやっていることはまだグラフィックライブラリを使用しています。ライブラリはGDIと呼ばれ、OSのメインAPIの一部ですが、技術的にはグラフィックライブラリです。
ファラプ

回答:


41

実行速度だけでなく、シンプルさも重要です。この例で使用されるソフトウェアレンダリングは、ハードウェアアクセラレーション(GPUなど)を使用するよりもはるかに遅くなりますが、画面上にいくつかのビットマップを描画することは、パフォーマンスの低下に気付かないほど簡単なタスクです。

ただし、三角形のラスタライズ、深度ソートなどの低レベルのアクティビティは、GPUがいくつかのコマンドで暗黙的に処理できるよく理解されている概念です。これらをソフトウェアモードで再実装することは、本質的に車輪を再発明することです。レンダリングがどのように行われるかを低レベルで理解したい場合はこれで問題ありません。私自身は少し探求するために3Dソフトウェアレンダラーを作成しましたが、ほとんどの場合、ボックス。

指定した例は非常に基本的なもので、画面上に単一の画像を描くだけなので、実装は簡単です。ただし、複雑さの階層化を開始すると、すべてを正しくレンダリングすることがますます複雑になることがわかります。3DソフトウェアレンダリングのQuake時代に人々がやり直さなければならなかったものは正気ではありませんでしたが、私はあなたがそこまで(まだ)行かないことを感謝しています。


12
OpenGLは、点、線、三角形などの用語を知っています。ほとんどの場合、三角形を使用します。OpenGLの操作方法を学ぶためにopengl-tutorial.orgをお勧めしますOpenGLが内部で
tkausl

1
+1するつもりでしたが、コンピューティングの歴史に関して間違った印象を与えると思うので、「車輪の再発明」について少しは好きではありません。ビットマップレンダリングが最初に登場したため、OpenGLは「車輪の再発明」でした。ただし、そうする理由は2つあります。1)標準化と2)GPUアクセラレーションです。ホイールの再発明は、新しいバージョンが改善されている場合(つまり、タイヤ付きホイールと木製ワゴンホイール)には必ずしも悪いことではありません。ここで重要な点は、ソフトウェアレンダリングが車輪を再発明しているということではなく、GPUレンダリングよりも劣っていることです。
ファラプ

4
それを除く外@Pharap 絶対にかかわらず、それは歴史的にしたかどうかの、車輪の再発明されたソフトウェアレンダラを書いて、。
-porglezomp

1
これは半分の答えです。次の答えは残りの半分ですが、完全な答え(OpenGLと彼が言及した他のものとの違いについての少しの説明を含む)は、この質問に対する適切な答えです。
ジャスパー

1
@ user148013「openglは点、線、三角形などの用語を知っていますか?」最新のOpenGLは、これらのプリミティブのみを扱います。それら以外はラスタライズできません。
ナックス 'vi-vim-nvim'

25

私の質問は、単にバッファを割り当て、ビットマップを渡して画面に描画するだけでよいのに、なぜopen gl、sfml、sdlのようなものを使用する必要があるのでしょうか?

ショート:高速だから(OpenGL、DirectX)。

長いです:

これはすべて自分でできると思うかもしれません。画面にピクセルを描画します。四角形や三角形などの図形を描画する小さなライブラリを作成する場合があります。もちろん、これは機能します。まさにこれを行うためのライブラリがたくさんあります。そのうちのいくつかはOpenGL仕様を実装しているため(openglのソフトウェア側のようなものです)、Casey Muratoriが行うことを正確に実行します。ソフトウェア側ですべてを計算し、ソフトウェア側でピクセルを設定して、結果を画面に書き込みます。

しかし、これは遅いです。最終的にこれらすべてを実行するCPUは、このシナリオ用には作成されていません。それがGPUの目的です。OpenGLが行うこと(もちろんソフトウェア実装でない限り)は、すべてのデータ、すべての描画呼び出し、ほぼすべてをグラフィックスカードにプッシュし、GPUに作業を行うように指示することです。GPUは、この種のジョブ専用に作られています。浮動小数点数(あなたは何をすべきかザッツ掛ける多くの 3Dシーンを描画するときに)とシェーダを実行します。そしてこれは並行して。GPUの速さを把握するために、1920x1080ピクセルのフルスクリーンで3Dのシンプルなシーンを考えてください。これらは、2,073,600ピクセルを乗算して描画されます。以下のためのすべての単一ピクセルの場合、GPUはフラグメントシェーダーを少なくとも1回実行し、ほとんどの場合は複数回実行します。ここで、1秒あたり60フレームで実行するとします。つまり、GPUはフラグメントシェーダーを2,073,600 * 60 = 124,416,000回/秒で実行します。CPUでこのようなことができると思いますか?(これは非常に簡単な説明です。より近いオブジェクトでオーバードローするピクセル数、使用するMSAAの量など、さらに多くのことを考慮する必要がありますが、1秒あたり124,416,000回はおそらく最も低く、 '簡単なシーンで60fps以上を簡単に取得できます)

それはOpenGLとDirect3Dが行うことであり、どのエンジンに対して@Uri Popovsが答えを見るかです。


8
彼は2Dゲームを作成していますが、それは3Dと同様の別のトピックです。また、遅いと言う、必ずしも60 fps未満というわけではありませんが、少なくとも3Dスペースに関しては、グラフィックスカードがCPUが必要とする時間のほんの一部で同じジョブを実行することを意味します。
tkausl

4
GPUが優れている理由は、シェーダー呼び出しを並列化するようにセットアップされているためです。
ラチェットフリーク

4
@ user148013この男から私が見たものから、彼は「非常に賢い」の正反対だと思います。
Bartek Banachewicz

4
レンダリングが遅いだけではありません(Caseyのソフトウェアレンダラーは驚くほど高速でした)。また、一般的なRAMからビデオRAMにプッシュし続けるには大量のデータが必要です。バスの種類によっては、巨大なビットマップをビデオカードにプッシュするのに、フレーム時間がかなりかかる場合があります。GPUを使用して、テクスチャを時々プッシュし、フレームごとに使用します。
エイドリアンマッカーシー

2
@ user148013派手なプログラミングと優れたプログラミングには違いがあります。それらは重複する可能性がありますが、多くの場合、競合しています。私は「MESAができるように…ソフトウェアでレンダリングできる」を派手で、間違いなく良くない下に置いた。

11

彼が行うことはソフトウェアレンダリングと呼ばれ、OpenGLが行うことはGPUレンダリングと呼ばれます

それらの違いは何ですか?速度とメモリ。

ラスタライズ(画面上の三角形の塗りつぶし)には時間がかかります。CPUでそれを行う場合、特に適切に最適化されていない場合、ゲームロジックからその時間を本質的に奪います。

そして、画像がどれだけ小さいかは重要ではありません。彼はそれのために一定量のメモリを割り当てる必要があります。GPUには、このためのビデオメモリがあります。


OS Xでもソフトウェアレンダリングは可能ですか?なぜなら、グラフィックスに関係することはすべてOpenGlが今やMetalによって行われたようだからです。
user148013

2
@ user148013いくつかの誤解があります。それはので、OpenGLは、マルチプラットフォームのAPIであることができ、OS X上で動作し、実際にそれが「現代」(ポスト2000)GPUですべてで実行することができます。Metalは、Appleデバイス専用の独立したAPIです。ソフトウェアレンダリングも、これらの両方とは別のものです。もちろん、OS Xでも実行できます。基本的には、CPUを使用して画面上でピクセルを手動で設定するだけです。
バリント

私が尋ねた理由はまさに、ソフトウェアレンダリングがOS Xでできないことを知っているからです。CocoaはOpenGlに手を伸ばし、QuarzはOpenGlを使用し、Core FrameworkはOpenGlを使用します。彼らは現在、より高速な方法としてメタルを使用しています。しかし、GPU(OpenGl、Metal)を使用せずに画面にバッファーを描画する単一の関数は見つかりませんでした。
user148013

1
@ user148013それはOSや実装に固有のものではないからです。Javaで実装したいとしましょう。これは、マルチプラットフォーム開発の有名な選択肢だからです。Javaを使用すると、最初にウィンドウ(JFrame)を作成し、次にその上に直接描画するのではなく、画像上に描画してから、この画像をフレーム上に配置することでそれを行うことができます。ただし、「三角形」または「線」という用語はわかりません。色のみ。ラスタライズアルゴリズムを使用して自分で実装する必要があります。これがOpenGLを好む理由です。より高速で、少し使いやすいです。基本的にはラスタライズAPIです。
バリント

2
@ user148013なぜできなかったのですか?ウィンドウを開くことができ、APIを使用せずに1つのイメージを描画できる場合、できます。
バリント

8

他の人からの答えは私が答えるよりも正確ですが、あなたの質問の根底にあると思うソフトウェア開発の仕組みについての基本的な誤解を指摘したいと思います。フレームワークなしで「自分で」物事を行うことは常に可能であり、そうすることから多くの教育的利益がある場合が多いですが、現実はそれが現代のソフトウェアの作成方法ではないということです。

誰かがハードウェアとそれを実行する機械語を作成しました。他の誰かが、高レベルの言語とコンパイラー、ドライバーとオペレーティングシステム、グラフィックスライブラリなどを作成しています。私たちはそれぞれ、前任者の仕事に基づいています。それは「大丈夫」だけでなく、要件です。

ツールチェーン内の任意のポイントで、「許容される」ものまたはそうでないものの線を引きます。「アセンブリで同じことができるのにC ++を使用する理由」と簡単に言うこともできますし、「配線から出る電圧を簡単に読み取って自分で計算できるのにキーボードドライバーに頼るのはなぜですか?」誰もが自分ですべてを行うには、1日の時間も生涯の年も十分ではありません。

これはソフトウェア開発だけでなく、一般的な現代生活にも当てはまります。トースターを自分で作った男を一から聞いたことはありますか?http://www.thomasthwaites.com/the-toaster-project/。本当に長い時間と多大な努力を要しました。トースター用。ビデオゲームを実現するために必要なものすべて自分で構築てみてください!


2
教育目的のために車輪を再発明するという考えを軽視せずにフレームワークを使用するのが良い理由を述べているので、これは良い答えだと思います。
ファラプ

3

エンジンは、画面に絵を描くだけでなく、はるかに多くのことを行います。照明、影、入力、衝突検出を処理します。レンダリング部分だけでも、画面にバッファをプッシュするよりもはるかに複雑です。特に3Dシーンでは、ビットマップよりもはるかに複雑なデータで多くの計算を行う必要があります。私はあなたに車とのアナロジーを与えましょう:あなたが単純であると言っているのは車の排気です。適切なサイズのパイプを作成し、ガスを一端から他端に押します。しかし、これは車のメカニズムで起こっている唯一のものからはほど遠いです。


3

上記の回答は優れていますが、OpenGLなどが優先される理由に関する最も重要な理由を実際に説明するものはありません。主な理由は、画面上の何百万ものピクセルをレンダリングするようなもの、GPUで動作するように特別に設計された専用ハードウェアを利用することです。

CPUを使用したソフトウェアレンダリングでは、レンダラーはビットマップ上のすべてのピクセルを1つずつループし、画面に表示するように命令を発行します。したがって、1000x1000サイズのイメージをレンダリングする場合、CPUが1,000,000ループを超えるとループします。結局のところ、コントロールを念頭に置いて設計されています。多くのif条件、1つの命令セットから別の命令セットへのジャンプ、および制御フローの厳密な方向。ただし、GPUは、画面上のピクセルに対して同様のループを多数実行することを認識して設計されています。GPUは、1000000回の繰り返しでforループを実行し、膨大な数のコアに作業を分割して、それぞれが並列に**相互に独立して**動作するようにします。したがって、CPUとは異なり、GPUがif-else条件に遭遇するたびに、GPUはそれ自体の2つのコアへの両方のコードブランチを処理し、最後に、条件の評価結果を調べて破棄します不要なブランチの結果(GPUシェーダーの多くのif-else条件が眉をひそめるのはそのためです;それらは常に無駄に責任があります)。

はい、GPUは並列処理を中心に構築されています。これにより、CPUに比べてピクセルの処理がはるかに高速になります。


0

参照ドゥ私は本当にグラフィックスAPIを使用する必要がありますか?

確かに、バッファを要求し、バッファにいくつかのビットを設定して、画面に書き込むことができます。それは、3DFXから90年代半ばにグラフィックアクセラレータが利用可能になるまで、PCでグラフィックプログラミングを行う唯一の方法でした。Windowsでも、DirectXはビデオメモリに直接アクセスできるように開発されました。

しかし、PC以外のハードウェア、専用のゲーム機では、プロセッサからの作業をオフロードすることでグラフィックスを高速化する技術が常にありました。Atari 2600にも「ハードウェアスプライト」がありました。これは、フレームバッファに十分なRAMがなかったことが一因です。

後期(80年代半ば)のゲームコンソールは、プラットフォームゲーム用に最適化されました。繰り返しますが、フレームバッファはありません。代わりに、プログラマはタイルのグリッドを指定できます。

Genesisグラフィックハードウェアは、2つのスクロール可能なプレーンで構成されています。各プレーンはタイルで構成されています。各タイルは、ピクセルあたり4ビットの8x8ピクセルの正方形です。したがって、各ピクセルは16色を持つことができます。各タイルは4つのカラーテーブルのうち1つを使用できるため、画面上では一度に64色を取得できますが、特定のタイルでは16色しか使用できません。タイルには32バイトが必要です。64Kのグラフィックメモリがあります。これにより、メモリが他に使用されない場合、2048個の一意のタイルが許可されます。


-2

最新のCPUはソフトウェアで2Dゲームを実行するのに十分高速であるため、2Dグラフィックスの場合、OpenGL / DirectXは利点を提供しません。たとえば、3Dプロジェクションマトリックスを設定して束を描くスプライトとGPUへのデータのアップロード。

OpenGLでは、すべてのスプライトを512x512テクスチャ(PSXなどの古いコンソールのアーティファクト、ビデオメモリページにグラフィックをパック)内にすべてパックする必要があり、かなり複雑なスプライトパッキングコードを記述する必要があります。

一方、3Dを実行し、複雑なシェーディングで数百万の三角形をレンダリングする場合、GPUは避けられません。かなり前に、DirectDrawと呼ばれるDirect3dのより単純な2dのみのバージョンがありました。GPUはスプライト描画を加速しましたが、現在はMicrosoftはサポートしていません。 。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.