OpenGLの学習(四) - 三角形を作成します

免責事項:この記事はブロガーオリジナル記事です、続くBY-SAのCC 4.0を著作権契約、複製、元のソースのリンクと、この文を添付してください。
このリンク: https://blog.csdn.net/qq_39030818/article/details/102603340

LearnOpenGL-- https://learnopengl-cn.github.io/

3つの用語:

  • 頂点配列オブジェクト:頂点配列オブジェクト、VAO
  • 頂点バッファオブジェクト:頂点バッファオブジェクト、VBO
  • インデックスバッファオブジェクト:要素バッファオブジェクト、EBOやインデックスバッファオブジェクト、IBO

これら三つのことに言及するとき、あなたは、完全な名前を使用することも略語を使用することができ、元の時間の一貫性のある翻訳および維持します。間隔としての英語には単語がありませんので、中国の一部のフルネームは容易でノートではないかもしれません。しかし、覚えている略語と中国は事の完全な名前を参照してください。

OpenGLのでは、3D空間内のそのすべてのもの、そしてスクリーンとウィンドウが仕事のほとんどは、OpenGLの3Dはあなたのスクリーンを適応させる2Dピクセル座標に上で、その結果、画素の2次元配列です2Dは、OpenGLのプロセスの座標に3D座標レンダリング・グラフィックス・パイプライン(グラフィックス・パイプライン、主に翻訳パイプラインは、実際には、最終的に画面に表示されるプロセスの間に様々な変更を介してパイプラインを介して元の図形データの束を指しプロセス)の管理。あなたの2Dは3D座標を座標、および第2の部分は2Dは、画素の実際の色に調整され変換する第一部:グラフィックスレンダリングパイプラインは、2つの主要部分に分けることができます。このチュートリアルでは、簡単にグラフィックスレンダリングパイプラインを議論し、どのようにそれはかなりのピクセルを作成することができます。

2Dおよびピクセル座標が異なっている、2Dは2D画素点の近似である2次元空間内の点の正確な表現を座標、スクリーン/ウィンドウ解像度の制限された2次元画素です。

3次元座標のセットを受け入れ、[画面出力に2Dカラーピクセルにそれらを変換するためにグラフィックスレンダリングパイプライン。グラフィックスレンダリングパイプラインは、いくつかの段階に分けることができ、各ステージは、入力として、前の段の出力であろう。すべてのこれらの段階は、高度に(特定の機能を有する)特化され、容易に並行して行われます。彼らは自分の小さなプログラムを実行する並列実行、ほとんどのカードが今日持っている小さな処理コアの数千人、(パイプライン)としてGPU上でそれらの各段階の特徴を持っているので、それは、あるパイプラインをレンダリングするので、高速グラフィックスあなたのデータを処理します。これらの小さなプログラムと呼ばれるシェーダ(シェーダ)。

いくつかのシェーダは、私たちはデフォルトを置き換えるために、独自のシェーダを書くことを可能にする、開発者が独自に設定することができます。そのように、我々はより密接に、パイプラインの特定の部分にグラフィックスレンダリングを制御することができますが、また、彼らは、GPU上で実行するので、彼らは貴重なCPU時間を節約私たちを与えることができるので。OpenGLのシェーディングは、OpenGLのシェーディング言語(OpenGLのシェーディング言語、GLSL)の中に書かれています

頂点データは、頂点の集合である。まず、我々は、頂点データ配列は(頂点データ)と呼ばれる三角形を表すために使用されるパイプライン入力をレンダリングする3Dグラフィックスのような3つの座標の配列を渡します。頂点(頂点)の座標データ、3Dの集合です。頂点データは、頂点属性表現(頂点属性)、それは我々が使用する任意のデータを含めることができ、それを簡単にするために、我々は、3次元位置(注釈1)の各頂点を想定し、カラー値の数からなります。

それは「空間」は、この特定の場所属性表す場合、我々は、「位置」について話すとき、また、X、Y、Z三次元座標系、X、として、座標のいずれかと「空間」を意味しますY二次元座標系、又は直線上のxとyの間の線形関係が、二次元座標系偏平スペースが平坦であり、そして直線は、非常に薄く長い空間です。

OpenGLは私たちの座標とカラー値が構成され、最後にものを知ってもらうためには、OpenGLのレンダリングが表現されたデータのタイプを指定する必要があります。私たちは、これらのデータがポイントのシリーズとしてレンダリングされることを願っていますか?一連の三角形?それとも、長蛇の列?これらのヒントを作る、と呼ばれるプリミティブ(原始的)、任意の命令は、OpenGLに渡す描画プリミティブを呼び出します。GL_POINTS、GL_TRIANGLES、GL_LINE_STRIP:これは数少ないです。

最初の部分は、パイプラインレンダリンググラフィックである頂点シェーダ入力として単一の頂点を追加する(頂点シェーダ)。頂点シェーダの主な目的は、頂点シェーダ頂点属性は、基本的なプロセスに私たちを可能にしながら、別の3Dは、3次元座標(後述)への座標です。

プリミティブ組み立て(それが頂点である場合、GL_POINTS、)入力として全ての頂点(プリミティブ・アセンブリ)頂点シェーダ出力段、およびプリミティブ指定された全ての点の形状に組み立てられた、本実施例のセクションには、三角形です。

出力プリミティブ・アセンブリステージはに渡されるジオメトリシェーダ(ジオメトリシェーダ)。新しい頂点(または他の)の新しい構造を生成することができ、入力フォームなどのプリミティブの頂点の集合にジオメトリシェーダは、追加の基本形状を生成します。例えば、それは別の三角形を生成します。

出力ジオメトリシェーダステージは、それがフラグメントシェーダ(フラグメントシェーダ)で使用するためのフラグメント(断片)を生成する、そのような最終的な画面上の対応する画素としてマッピングされた格子(ラスタライズステージ)、渡されます。フラグメントシェーダ前操作(クリッピング)を切断行います。効率を高めるために、あなたの視野の外のすべてのピクセルを超えて破棄を切断。

OpenGLは、ピクセルレンダリングのOpenGL必要なすべてのデータの断片です。

フラグメントシェーダ主な目的は、すべての高度なOpenGLの効果が生成ここで、最終的なピクセル色を計算することです。典型的には、3Dシーンのフラグメントシェーダを含むデータは、(例えば、照明、シェーディング、光の色、など)は、そのようなデータは、最終的なピクセルの色を計算するために使用されてもよいです。

最終的な目的は、最終段階に渡されるかを決定するために、対応する色値のすべての後、我々は、と呼ばれるアルファテストを混合(配合)段階。ピクセルは、他のオブジェクトのまたは前後にあることを決定するためにそれらを使用し、(後で話す)この段階フラグメント値で検出された深さ(及びテンプレート(ステンシル))に対応し、それは破棄されるべきかどうかを決定します。この段階は、(ブレンド)のアルファ値(アルファ値は、オブジェクトの透明度を定義する)とオブジェクトが混在しているチェックします。したがって、場合でも、フラグメントシェーダで算出された画素の色出力は、三角形の最終的なピクセル色の複数をレンダリングするときには完全に異なっていてもよいです。

あなたはそれが設定可能な多くの部分が含まれている、グラフィックスレンダリングパイプラインが非常に複雑で、見ることができます。しかし、ほとんどの場合のために、私たちはライン上の頂点とフラグメントシェーダを設定する必要があります。ジオメトリシェーダはオプションで、それは通常のライン上のデフォルトのシェーダです。

現代のOpenGLのでは、我々はしなければならない頂点シェーダとフラグメントシェーダ(GPUの頂点/フラグメントシェーダがないためデフォルト)の少なくとも一つを定義します。このような理由から、ちょうどあなたがあなたの最初の三角形が多くの知識を知る必要がありますレンダリングすることができます前にあるため、非常に困難になる可能性が現代のOpenGLを学ぶために始めて。あなたは、最終的な三角形をレンダリングするこのセクションの最後では、グラフィックスプログラミングの知識の多くを学ぶことができます。

頂点入力

あなたは、グラフィックスを描画するために開始する前に、我々はいくつかの頂点データをOpenGLを与える入力する必要があります。OpenGLは、3Dグラフィックスライブラリであるので、我々はすべての座標は、OpenGLの3次元座標(x、y、およびz)に指定されています。OpenGLは単に置かれていない全ての3Dは、画面上に2次元の画素に座標を、OpenGLの3Dは、三の軸(X、Y、及びZ)上の座標のみときに、-1.0〜1.0の範囲内にある場合にのみ処理されます。すべての座標は、いわゆる正規化装置座標(正規化デバイス座標)画面上の最終的なショーの範囲(座標がこの範囲外にある表示されない)であろう。

私たちは、三角形をレンダリングしたいので、私たちは、それぞれが3次元位置を持って、3つの頂点の合計を指定します。我々は、に正規化デバイス座標(OpenGLの可視領域)の形でそれらを定義するfloat配列。

float vertices[] = {
    -0.5f, -0.5f, 0.0f,
     0.5f, -0.5f, 0.0f,
     0.0f,  0.5f, 0.0f
};

OpenGLのため、我々は、我々は0.0に設定し、頂点のZ座標を二次元の三角形をレンダリングしている、3次元空間で作業されています。この方法は、次に、三角形の各点の深さが、2Dのように見えるように(深さ)は、同じです。

一般的にあなたがブロックすることができ、あなたがそれを見ることはありません遠く他の画素からであれば、それは資源を節約するために破棄され、宇宙の画素とあなたの距離を表す奥行きZ座標、として理解することができます。

正規化装置座標(正規化デバイス座標、NDC)

頂点は、頂点シェーダの座標あなたが処理されたら、それらはあるべきで正規化デバイス座標、正規化デバイス-1.0〜1.0の短い空間においてX、YおよびZの座標値です。座標は任意の破棄/カットの範囲外になる、それはあなたの画面上に表示されません。以下は、私たちの三角形は、標準化されたデバイス座標(z軸を無視して)で定義されて表示されます。

 

NDC

 

Y軸正方向が上向きである異なる通常画面座標(0、0)は画像の中心の座標ではなく、左上隅です。最終的に、あなたはそれ以外の場合は、彼らが表示されていない、すべての(変形した)座標空間での座標を求めています。

その後、正規化されたデバイスは、座標に変換します画面空間座標あなたはglViewport関数が実行するデータを用いて提供される(画面空間座標)、ビューポート変換を完了(ビューポート変換します)。得られたスクリーン空間座標は、フラグメントにフラグメントシェーダの入力に変換されます。

頂点シェーダ:後で定義このような頂点データは、我々は、パイプライン処理ステージをレンダリングするグラフィックスへの第1の入力として送信されます。これは、GPUのメモリを解釈し、グラフィックスカードに送信する方法を指定する方法をOpenGLを設定し、当社の頂点データを格納するメモリを作成します。頂点シェーダは、次に我々は、メモリの指定された量で頂点を処理します。

我々は、頂点バッファオブジェクト(頂点バッファオブジェクト、VBO)を介して、このメモリを管理し、それは頂点の多数に記憶される(多くの場合、メモリと呼ばれる)GPUメモリであろう。これらのバッファオブジェクトを使用する利点は、我々はむしろ一度、各頂点を送るよりも、グラフィックカードにワンタイム多数のデータを送ることができるということです。データは、グラフィックスカードにCPUから送信された比較的遅いので、我々は限り、一度にできるだけ多くのデータを送信しようとする可能性として試してみて下さい。場合は、メモリカードに送信されるデータ、頂点シェーダ非常に速いプロセスであり、頂点、ほぼ即時アクセス。

頂点バッファオブジェクト私たちの中にあるOpenGLの OpenGLのオブジェクトは、最初のチュートリアルが登場。OpenGLで他のオブジェクトと同様に、このクッションは、固有のIDを持っているので、私たちは、バッファglGenBuffers機能を使用してVBOのオブジェクトIDを生成することができます。

unsigned int VBO;
glGenBuffers(1, &VBO);

多くのOpenGLバッファオブジェクトタイプ、バッファタイプの頂点バッファオブジェクトがGL_ARRAY_BUFFERであります。OpenGLは限り、彼らは、バッファの異なる種類がありますように、私たちは同時に複数のバッファをバインドすることができます。私たちは、GL_ARRAY_BUFFERを標的に結合し、新しく作成されたバッファにglBindBuffer機能を使用することができます。

glBindBuffer(GL_ARRAY_BUFFER, VBO);  

この瞬間から、我々は(GL_ARRAY_BUFFERターゲット上)いずれかを使用すると、現在バインドされているコールのバッファバッファ(VBO)を構成するために使用されます。その後、我々はglBufferData関数を呼び出すことができ、それは、以前に定義されたバッファメモリに頂点データをコピーします。

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

glBufferDataは、具体的には、現在の結合バッファーのユーザ定義関数にデータをコピーするように設計されています。現在ターゲットGL_ARRAY_BUFFERにバインドされた頂点バッファオブジェクト:その最初のパラメータは、目標バッファタイプです。シンプルで、第2のパラメータは、送信データ(バイト)のサイズを指定sizeofライン上の頂点データのサイズを計算します。3番目のパラメータは、我々が送信する実際のデータです。

4番目のパラメータが、我々は与えられたグラフィックスデータを管理する方法を指定します。これは3つの形式があります。

  • GL_STATIC_DRAW:ほとんど、あるいはまったく変更したデータ。

  • GL_DYNAMIC_DRAW:データが大量に変更されます。

  • GL_STREAM_DRAW:データは、あなたが描くたびに変更します。

三角形の位置データが変化しない、彼らは電話をレンダリングするたびに同じままなので、GL_STATIC_DRAWのタイプを使用するのが最善です。例えば、データ・バッファが頻繁に変更され、場合は、タイプはGL_DYNAMIC_DRAW又はGL_STREAM_DRAW使用され、これは、確実に高速書き込みが可能なメモリカード部分のデータ。

今、私たちはVBO頂点バッファオブジェクト管理で、グラフィックスメモリに保存された頂点データを持っていること。ここでは、実際にデータを処理するために、頂点とフラグメントシェーダを作成します。今、私たちは今、それらを作成し始めています。

頂点シェーダ

頂点シェーダ(頂点シェーダ)は、プログラマブルシェーダのほんの一部です。私たちは、その後、レンダリングを行うために近代的なOpenGLを予定している場合、我々は、少なくとも一つの頂点とフラグメントシェーダを設定する必要があります。私たちは、簡単にシェーダを説明し、私たちの最初の三角形を描画するために2つの非常にシンプルなシェーダーを設定します。私たちは、次のセクションでより詳細にシェーダを説明します。

私たちが行う必要がある最初の事は、シェーダ言語GLSL(OpenGLのシェーディング言語)頂点シェーダの書き込みを使用して、我々はプログラムの中でそれを使用することができるように、シェーダをコンパイルすることです。あなたが見る下記のソースコードは、非常に基本的なGLSLの頂点シェーダであります:

#version 330 core
layout (location = 0) in vec3 aPos;

void main()
{
    gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}

あなたはGLSLは、C言語によく似て、見ることができます。各シェーダは声明をリリースし始めています。OpenGLと3.3以降では、バージョン番号とバージョンのGLSLのOpenGLは(バージョン420 GLSLのOpenGL 4.2に対応する、など)一致しています。我々はまた、それを明確に私たちはコアモードを使用することを作りました。

次に、使用するin頂点シェーダ内のすべての入力頂点属性(入力頂点属性)を宣言するために、キーワードを。今、私たちは唯一の場所(位置)データを気に、私たちは一つだけの頂点属性を必要とします。GLSL 1-4含まベクトルデータタイプ有するfloat接尾番号から見ることができるの数を含む、成分を。各頂点は、3D座標を有しているので、我々は、作成されvec3た入力変数をAPOS。また、によってlayout (location = 0)、我々は、この位置の値を必要とする理由の入力変数(場所)の位置の値を設定しますが、後に表示されます。

ベクトル(ベクター)

グラフィックスプログラミングでは、それは簡潔に任意のスペースの位置と方向を表現するため、私たちはしばしば、このベクトル数学的概念を使用し、それは非常に便利な数学的性質を有します。四つの成分のベクトルGLSLアップにおいて、各成分の値とすることができる座標空間を表すvec.xvec.yvec.zおよびvec.w得ました。その注意vec.wコンポーネントを、それがなく、いわゆる透視分割(視点部門)と、空間内の位置(ここでは、3D、4Dを扱っていない)として表現されていません。私たちは、ベクターのチュートリアルの後半で詳しく説明します。

頂点シェーダの出力を設定するために、我々は、シーンの背後にある定義済みのgl_Position変数に割り当てられたデータ配置する必要がありvec4タイプを。最後の値は、我々は、頂点シェーダとなり、出力のgl_Position主な機能を設定します。私たちの入力は3成分ベクトルであるので、我々は4つの成分に変換する必要があります。我々は置くことができるvec3ように、データをvec4しながら、パラメータのコンストラクタwコンポーネントに設定され1.0f、このタスクを達成するために(私たちは、なぜ、後で説明します)。

現在の頂点シェーダは、我々は、入力データの処理には何もないので、最も簡単な頂点シェーダーを考えることは、シェーダの出力を渡し置くことができるということかもしれません。データは正規化デバイス座標は通常ではありませんので、我々は最初の最初の表示可能領域でのOpenGLに変換する必要があり、実際のプログラムを入力します。

おすすめ

転載: blog.csdn.net/qq_39030818/article/details/102603340