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