2016-07-06 5 views
1

2Dシーン(オルト)を描画するにはどうすればよいか理解してください。私はシェーダでOpenGLを使用しています。シーン/ビューポート外のオブジェクト(OpenGL)

たとえば、ビューポートのサイズが800x600で、四角形を描いているとします。いくつかのクワッドはビューポートにあり、いくつかはビューポートにありません。

ビューポートから外れているクワッドは、OpenGLとシェーダによって処理されていますか? 「はい」の場合は、描画機能から切り取る必要がありますか? この状況には標準的な決定(glEnable(???))がありますか、それとも自分で作る必要がありますか?

ドロー:

void Draw() 
{ 
    glUseProgram(ProgramId); 
    glUniformMatrix4fv(MVPId, 1, GL_FALSE, (float*)pMVP); 

    glEnableVertexAttribArray(0); 
    glEnableVertexAttribArray(1); 
    glEnableVertexAttribArray(2); 

    glBindBuffer(GL_ARRAY_BUFFER, BaseQuadBufferId); 
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); 

    glBindBuffer(GL_ARRAY_BUFFER, BaseColorBufferId); 
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0); 

    glBindBuffer(GL_ARRAY_BUFFER, OffsetQuadBufferId); 
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, 0); 

    glVertexAttribDivisor(0, 0); //basic size 
    glVertexAttribDivisor(1, 0); //basic color 
    glVertexAttribDivisor(2, 1); //offset 
    glDrawArraysInstanced(GL_QUADS, 0, 4, QuadCount); 

    glDisableVertexAttribArray(0); 
    glDisableVertexAttribArray(1); 
    glDisableVertexAttribArray(2); 
} 

MVP:

CameraPosition = glm::vec3(0,0,1); 
CameraDirection = glm::vec3(0,0,0); 
Projection = glm::ortho(0.0f, 800.0f, 0.0f, 600.0f, -1.0f, 1.0f); 
Model = glm::mat4(1.0f); 
View = glm::lookAt(CameraPosition, CameraDirection, glm::vec3(0,1,0)); 
MVP = Projection * View * Model; 

バーテックスシェーダ:質問と

layout(location = 0) in vec3 vertexPosition; 
layout(location = 1) in vec4 vertexColor; 
layout(location = 2) in vec2 vertexOffset; 

uniform mat4 MVP; 
out vec4 Color; 

void main() 
{ 
    gl_Position = MVP * vec4(vertexPosition + vec3(vertexOffset.xy,0), 1); 
    Color = vertexColor; 
} 

画像: http://imgur.com/VckmghQ

答えて

1

すべての頂点glDraw ...を使用してサブミットされたものは、頂点シェーダ(およびジオメトリシェーダおよび/またはシェーダシェーダが使用されている場合はジオメトリシェーダおよび/またはシェーダシェーダ)によって処理されます。頂点処理段階(頂点、テッセレーションおよびジオメトリシェーダ)のクリッピングが適用された後でのみ可能です。クリッピング後、ビューポート&のシザー矩形に落ちて、ピクセル所有テストに合格したフラグメントのみが処理されます。

+0

クリッピングするには良い方法がありますか?シーンが動いてクワッドが残っている場合は、頂点バッファを備えた「ゾーン」を準備し、シーンの「ゾーン」の一部がその「ゾーン」を描画しないときに、この良い決定をしますか? – SomeCoder

+0

@SomeCoderこれにはかなり標準的な方法があります。プロセスはしばしば "視錐台のカリング"と呼ばれ、BSPツリーやオクツリーのようなデータ構造を使用することができます。それは本当に価値があるかどうかは、あなたが合計しているオブジェクトの数と、いつでもビュー内のオブジェクトの数に依存します。 –

+0

@Reto Koradi非常に興味深い。ありがとう。 – SomeCoder

1

あなたの質問には、次のようなものがあります。可視領域の外にあるオブジェクトを自分で処理する必要がありますか?答えはいいえです。

OpenGLはすべてのプリミティブを自動的にクリップし、部分的に見えてもすべてが正しく表示されるようにします。技術的には、これはフラグメントシェーダが呼び出される直前に行われます。その理由は、プリビュアシェイダーステージがプリミティブを変換する可能性があるため、すべてのシェイダーステージ後にのみ決定を行うことができるからです。クリッピングは、正規化されたデバイス座標で(したがって3Dで、近平面および遠平面に対しても)行われます。

レンダリングパイプラインの詳細については、thisをご覧ください。

+0

あなたは、コールドロー機能の前に、すべての頂点から、クワッドを完全にまたは部分的に見える頂点だけをカットする必要があります。 – SomeCoder

+0

いいえ、私はそれを言っていませんでした。私は言った:彼らはOpenGLによって切り取られているので、画面の外にあるクワッドについては気にしないでください。 (パフォーマンスが悪いのでゲームを最適化する必要がない限り) – BDL

+0

今私は大丈夫です。ありがとう。 – SomeCoder

関連する問題