2015-10-15 20 views
6

キューブマップの6面すべてに1つのdrawcallでレンダリングしようとしています.GLキューブマップはオフスクリーンフレームバッファオブジェクトに添付されています。フレームバッファクリアカラーとフラグメントシェーダ出力の両方によって影響を受けます。ジオメトリシェーダを6回(面ごとに1回)呼び出すと、gl_InstanceIDが組み込みgl_Layerに割り当てられます。フラグメントシェーダステージはgl_Layer値を読み込み、 in.aに基づいてラスターをシェードします。面白い6人のすべてがgl_Layer値に依存する独自の色で塗りつぶされることが期待されます。ジオメトリシェーダを使用したCUBEMAPへのレイヤードレンダリング

#version 430 

// Ouput data 
layout(location = 0) out vec4 color; 

in int gl_Layer; 

void main(){ 
    color = vec4(0.5,0.5,0.5,float(gl_Layer)/255.0); 
} 

頂点シェーダ基本的に実行します。テストのために

は私が次のフラグメントシェーダでテクスチャのアルファチャンネルにレイヤーIDをレンダリングしようとしている正しいgl_layer値を取得していますことを確認します何も:

#version 430 

in vec3 position; 


void main(){ 
    gl_Position = vec4(position, 1.0); 
} 

及びジオメトリシェーダーは、6回の実行単位正方形(全体のビューポートをカバーする)をレンダリングしgl_InvocationIDに従ってgl_Layer設定:

#version 430 

layout(triangles, invocations = 6) in; 
layout(triangle_strip, max_vertices = 4) out; 

out int gl_Layer; 

void main() 
{  
    const vec2 vert_data[4] = vec2[](vec2(-1.0, 1.0), vec2(-1.0, -1.0), vec2(1.0, 1.0), vec2(1.0, -1.0)); 

    for(int i=0; i<4; i++) 
    { 
     gl_Layer = gl_InvocationID; 
     gl_Position = vec4(vert_data[i].xy,0,1); 
     EmitVertex(); 
    } 

    EndPrimitive(); 
} 

そして最後に、これは私がテクスチャとフレームバッファを設定する方法である:

glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &fbtextures_count); 
    // how many textures to create? depends on complexity of your effects. 
    glActiveTexture(GL_TEXTURE0); 
    glGenFramebuffers(1, &framebuffer); 
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); 
    glGenTextures(1, &fbcubetexture); 
    GLenum target = GL_TEXTURE_CUBE_MAP; 

    // initializing color maps 
    glBindTexture(target, fbcubetexture); 
    glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
    glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 


    initData(255,255, 255); 
    for (int i = 0; i < 6; i++) 
    { 
     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA8, cube_s, cube_s, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); 
    } 

    glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, fbcubetexture, 0); 

    GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0 }; 
    glDrawBuffers(1, drawBuffers); 
    glReadBuffer(GL_COLOR_ATTACHMENT0); 
    glDrawBuffer(GL_COLOR_ATTACHMENT0); 
    glBindFramebuffer(GL_FRAMEBUFFER, 0); 

私は、クライアント上の顔の色を読んでいます:

for (int i = 0; i < 6; i++) 
{ 
    glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA,GL_UNSIGNED_BYTE, data); 
} 

私はGL_TEXTURE_CUBE_MAP_POSITIVE_Xために得る結果、正しい。残りの顔は同じ初期化値で保持されます。NVIDIA NSIGHTを使用してデバッグしましたが、キューブマップのテクスチャ全体が1つのフェースだけで表示されていました。

多ターゲットレンダリングでgl_Layer idをジオメトリシェーダを使用してどのように使用するかを示す数十の例を読んでいますが、それらのすべてが異なっています。

たとえば、FBOの1つのレンダーターゲットにキューブマップテクスチャを添付すれば十分か、または各フェースを別のレンダーターゲットにアタッチする必要があるかどうかは不明です。

glFramebufferTextureは、添付ファイルやglFramebufferTexture2Dを結合するために使用されべきでしょうか?

フレームバッファにcubemapが添付されている場合、glClearColorはすべての顔をある色または最初の色にクリアするはずですか?

私はここで何が間違っていますか?誰でも正しい方法を示すことができますか?

システムスペック:

GPU:NVIDIAのGeForce GTX 960 Windows7の64bit版 MSVC120

+0

glTexImage2D()は、ダウンロード/読み込み用ではなく、テクスチャデータのアップロード/書き込みに使用されています。テクスチャデータを読み込むには、glGetTexImage()を使用する必要があります。残りのコードは大丈夫です。オフスクリーン描画の前に正しいFBO(glBindFramebuffer())をバインドし、glViewport(0、0、cube_s、cube_s)を設定してからdrawを実行するようにしてください。 – Shot

+0

これはタイプです。実際にはglGetTexImage()でした –

答えて

1

私はこれが問題であることを証明することはできません。しかしそれは確かに1つの問題です:

for(int i=0; i<4; i++) 

GSは入力としてtrianglesを取ると言いました。さて、それらは3つのの頂点しか持っていません。あなたの三角形ストリップは、そこに悪い頂点を持ちます。

GS内の項目をループする、それがこれを行うには、常に安全です:

for(int i = 0; i < gl_in.length(); i++) 

こうすることで、あなたが入力プリミティブ型を変更した場合、あなたの長さが自動的に更新されます。

関連する問題