クワッドに白い色として定義された単純なテクスチャを適用して、OpenGL でテクスチャを練習しています。コードは正常にコンパイルおよび実行されますが、クワッドの色は、指定したように白ではなく、単に黒です。
フラグメント シェーダーが適切な種類のサンプリングを行っていないためだと思います。テクスチャから返されるデータのようなものです。関数はすべてゼロであるため、クワッドのテクスチャは黒くなります。私がそう思う理由は、プログラムを実行すると、白の明確な色を作成し、クワッドの頂点の 1 つを少し移動して背景を見ることができるためです (通常はサーフェス全体を埋めるため)。そこに白い背景がはっきりと見え、その上に黒いクワッドがあります。したがって、一部の出力カラーはフラグメント シェーダーから生成されます。提供した小さなピクセル配列は白色のみであるため、これは間違ったカラーです。問題は、私が持っているコードから間違った結果が生成される理由が正確にわからないことです。私は、同じコードまたはそれ以下のコードを使用する本をたどろうとしています。また、さまざまなチュートリアルで調べてみましたが、すべて同じアプローチを使用しているように見えるため、行き詰まっています。
[編集]
問題の一部を追跡しました。glGetError() を使用していくつかのエラー追跡を行ったところ、コードの次の行であることがわかりました。
glTexStorage2D(GL_TEXTURE_2D, 0, GL_RGB8, 4, 4);
2 番目のパラメーターレベルが 0であるため、エラー コード 1282 (無効な操作) が返されます。これを 1 に設定すると、エラーは消えます。問題は次の行になります。
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_R, GL_FLOAT, myTexture);
levelパラメータを変更しても修正されませんが、同じエラーが返されます。
これは、私が使用するフラグメントおよび頂点シェーダーです。
フラグメントシェーダー
// FRAGMENT SHADER
#version 330
uniform sampler2D tex;
in vec2 vs_tex_coord;
layout (location = 0) out vec4 outputColor;
void main(void)
{
outputColor = texture(tex, vs_tex_coord);
}
頂点シェーダー
// VERTEX SHADER
#version 330
layout(location = 0) in vec4 position;
layout(location = 1) in vec2 in_tex_coord;
uniform vec2 offset;
out vec2 vs_tex_coord;
void main(void)
{
vec4 finalOffset = vec4(offset.x, offset.y, 0.0, 0.0);
gl_Position = position + finalOffset;
vs_tex_coord = in_tex_coord;
}
テクスチャ オブジェクトの生成と保存に使用するコードは非常に単純です。
glGenTextures(1, &textureHandle);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureHandle);
glTexStorage2D(GL_TEXTURE_2D, 0, GL_RGB8, 4, 4);
const GLubyte myTexture[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_RGB, GL_UNSIGNED_BYTE, myTexture);
myTextureには、各コンポーネントが 4 ビットの RGB の内部形式で 4x4 テクスチャが含まれているだけです。全て白にしました。
次に、次のようにデフォルトのサンプラーを生成するだけです。
glGenSamplers(1, &mySampler);
glBindSampler(0, mySampler);
そして最後にレンダリングします:
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(theProgram);
GLuint samplerLoc = glGetUniformLocation(theProgram, "tex");
if (samplerLoc == -1)
printf("Location name could not be found...\n");
glUniform1i(samplerLoc, 0);
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(16 * sizeof(float)));
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
VBOにアップロードする配列は次のとおりです。
const float vertexPositions[] =
{
// Vertex position
-0.8f, -1.0f, 0.0f, 1.0f,
1.0f, -1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, 1.0f, 0.0f, 1.0f,
// Texture coordinates
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f
};
サンプラー オブジェクトを正しく使用していないためですか? 正しく動作させる前に、何らかの設定を行う必要がありますか? 中間ステップを見逃していますか?
興味のある方のために、視覚的な結果は次のとおりです。
意図的に頂点位置の 1 つを少し移動して、白い背景に対して黒いクワッドが見えるように、白くクリアされた背景を確認できます。