私は経験豊富な C++ プログラマーで、OpenGL の学習に取り組んでいます。とりわけ、Richard Wright のOpenGL Super Bibleを読んでいます。そこにあるサポート ライブラリはハッカー ヘッドの C で、大まかに C++ に翻訳されています。少し純粋主義者なので、サポート コードのほとんどを C++ に翻訳しました。そして、私は Glut ではなく QT で作業しています。第 2 章の例と第 3 章の「プリミティブ」の例は動作しましたが、「GeoTest」の例は正しく動作しません。問題の簡単な例を次に示します。
void geotest::paintGL() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_CULL_FACE);
model_view_matrix.push(view_frame);
float red[] = { 1.0f, 0.0f, 0.0f, 1.0f };
shader.use(
transform_pipeline.get_model_view_matrix(),
transform_pipeline.get_projection_matrix(),
red);
glBegin(GL_TRIANGLES);
glVertex3f(-1.2f, -1.2f, 0.0f);
glVertex3f( 1.2f, -1.2f, 0.0f);
glVertex3f( 1.2f, 1.2f, 0.0f);
glEnd();
model_view_matrix.pop();
}
これshader
は、本の を私が翻案したものGLT_SHADER_DEFAULT_LIGHT
です。問題を切り分けるために、図面を切り取りました。このコードを実行すると、一見空白のウィンドウが表示されます。ここに示していないコードは、画像の回転をサポートしています。x 軸または y 軸を中心に 180 度回転すると、三角形の反対側が見えますが、赤ではなく黒です。そのため、表面法線が最初は視聴者から離れているように見えるため、カリングされます。
glNormal3f(0.0f, 0.0f, -1.0f)
(and )との呼び出し1.0f
の間に想像できるすべての場所に1 ~ 3 個の呼び出しを追加しようとしましたが、効果は見られませんでした。三角形は常に背面が表示された状態で描画されます。glBegin
glEnd
法線に関する基本的なことが欠けていますか? 私はシェーダーが大丈夫であることを確信しています (本の GLT_SHADER_FLAT を使用すると、法線で同じ問題が発生しますが、三角形が表示されると赤になります)。
編集シェーダーのコードは次のとおりです。
const char *default_light_vp = "uniform mat4 mvMatrix;"
"uniform mat4 pMatrix;"
"varying vec4 vFragColor;"
"attribute vec4 vVertex;"
"attribute vec3 vNormal;"
"uniform vec4 vColor;"
"void main(void) { "
" mat3 mNormalMatrix;"
" mNormalMatrix[0] = mvMatrix[0].xyz;"
" mNormalMatrix[1] = mvMatrix[1].xyz;"
" mNormalMatrix[2] = mvMatrix[2].xyz;"
" vec3 vNorm = normalize(mNormalMatrix * vNormal);"
" vec3 vLightDir = vec3(0.0, 0.0, 1.0); "
" float fDot = max(0.0, dot(vNorm, vLightDir)); "
" vFragColor.rgb = vColor.rgb * fDot;"
" vFragColor.a = vColor.a;"
" mat4 mvpMatrix;"
" mvpMatrix = pMatrix * mvMatrix;"
" gl_Position = mvpMatrix * vVertex; "
"}";
const char *default_light_fp =
#ifdef OPENGL_ES
"precision mediump float;"
#endif
"varying vec4 vFragColor; "
"void main(void) { "
" gl_FragColor = vFragColor; "
"}";