GLSL4.2のImageLoad
機能の機能を実証するための簡単なテストプログラムを作成しようとしています。これまでのところ:
- から左下のテクセルをロードして
image2D
表示する単純なシェーダー。 - フルスクリーンの分隊を描画するためのいくつかの単純な頂点コード
- コンテキストを作成したり、シェーダーをコンパイルしたりするためのその他のスキャフォールディングコード。
これが私のフラグコードです(頂点は単純なパススルーシェーダーです):
#version 420
#include <gtest/SmallImage.h> //NOTE: I have a preprocessor that takes care of includes
layout(binding = SMALL_IMAGE_ONE_BINDING, rgba8) uniform image2D image_one;
smooth in vec2 texture_coords;
out vec4 out_color;
void main(void)
{
vec4 loaded = imageLoad(image_one, ivec2(0,0));
vec4;
out_color = vec4(loaded.r,
loaded.g,
gl_FragCoord.y/1200.0,
1);
}
非常にシンプルで、事故の余地はありません。imageLoad
ピクセル座標に比例する青いチャネルは、呼び出しが失敗した場合でも、クワッドが適切にレンダリングされていることを示しています。
これが私が画面にレンダリングするために使用しているC++ループです。テクスチャをバインドし、黄色のテクセルを1つ書き込み、フルスクリーンのクワッドをレンダリングします。2つのバリエーションがあります。MAKE_ONCE
が定義されると、ループの前にテクスチャが1回生成されます。定義されていない場合、ループの反復ごとに新しいテクスチャが生成されます。
MyTestFun(void)
{
glm::vec4 yellow = glm::vec4(1.0, 1.0, 0.0, 1.0);
#ifdef MAKE_ONCE
renderer->InitFrame(); //sets current OpenGL context
GLuint name = 0;
glGenTextures(1, &name);
renderer->EndFrame();
#endif
while(1)
{
renderer->InitFrame();
#ifndef MAKE_ONCE
GLuint name =0;
glGenTextures(1, &name);
#endif
glBindTexture(GL_TEXTURE_2D, name);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_FLOAT,
glm::value_ptr(yellow));
glBindTexture(GL_TEXTURE_2D, 0);
glBindImageTexture(SMALL_IMAGE_ONE_UNIT, name, 0, false, 0, GL_READ_ONLY,
GL_RGBA8);
renderer->FullscreenQuad(); //shades using the frag shader shown above
//bind the default texture to the image unit, hopefully freeing ours for editing
glBindImageTexture(SMALL_IMAGE_ONE_UNIT, 0, 0, false, 0, GL_READ_WRITE,
GL_RGBA8);
renderer->EndFrame();
}
}
が定義されている場合MAKE_ONCE
、最初のフレームは白から黄色への垂直方向のグラデーションを示しますが、後続のフレームは青から黒への垂直方向のグラデーションを示し、IMAGE_LOAD
呼び出しが0.0を返していることを示します。
が定義されていない場合MAKE_ONCE
、たとえば、テクスチャがすべてのフレームで再作成される場合、プログラムは期待どおりに動作し、すべてのフレームで同じ白<->黄色のグラデーションを示します。
この動作の原因は何ですか?OpenGL 4.2仕様ではimageLoad
、画像が無効な状態(p255-266)の場合、呼び出しは黒(すべてゼロ)を返すとされていますが、ここでは有効条件のいずれも適用されないようです。