シェーダーを使用して、VAO と一緒に描画してライティングを実行しようとしています。ただし、glNormalPointer をロードするたびに、シェーダーがオブジェクトに描画されず、デバッグに問題が発生します。
ここに私のコードの一部があります:
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glNormalPointer(GL_FLOAT, 0, normals);
glDrawElements(GL_QUADS, 400, GL_UNSIGNED_INT, indices);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
正しく描画されますが、ライティングが正しく行われません。通常の作業に使用される 3 行をコメント アウトすると、プログラムは正しく実行されますが、これは意味がありません。法線は、サーフェスの面の法線にすぎません。glNormal3f() と glVertex3f() を使用してそれらをロードすると、オブジェクトは以下のようにレンダリングされるため、正しいはずです。シェーダー ファイルは lighthouse3d Web サイトからのもので、正しくレンダリングされています。
これは glNormalPointer() が無効になっている場合です。
これは、コメントアウトされていないため、glNormalPointer が有効になっています。
私が逃したものはありますか?
シェーダー コードは次のとおりです。これは、lighthouse3d から取得した頂点シェーダーです。
varying vec4 diffuse,ambientGlobal,ambient;
varying vec3 normal,lightDir,halfVector;
varying float dist;
void main()
{
vec4 ecPos;
vec3 aux;
/* first transform the normal into eye space and normalize the result */
normal = normalize(gl_NormalMatrix * gl_Normal);
/* now normalize the light's direction. Note that according to the
OpenGL specification, the light is stored in eye space. Also since
we're talking about a directional light, the position field is actually
direction */
ecPos = gl_ModelViewMatrix * gl_Vertex;
aux = vec3(gl_LightSource[2].position-ecPos);
lightDir = normalize(aux);
/* compute the distance to the light source to a varying variable*/
dist = length(aux);
/* Normalize the halfVector to pass it to the fragment shader */
halfVector = normalize(gl_LightSource[2].halfVector.xyz);
/* Compute the diffuse, ambient and globalAmbient terms */
diffuse = gl_FrontMaterial.diffuse * gl_LightSource[2].diffuse;
ambient = gl_FrontMaterial.ambient * gl_LightSource[2].ambient;
ambientGlobal = gl_LightModel.ambient * gl_FrontMaterial.ambient;
gl_Position = ftransform();
}
これは、lighthouse3d から取得したフラグメント シェーダーです。
varying vec4 diffuse,ambientGlobal, ambient;
varying vec3 normal,lightDir,halfVector;
varying float dist;
void main()
{
vec3 n,halfV,viewV,ldir;
float NdotL,NdotHV;
vec4 color = ambientGlobal;
float att;
/* a fragment shader can't write a verying variable, hence we need
a new variable to store the normalized interpolated normal */
n = normalize(normal);
/* compute the dot product between normal and ldir */
NdotL = max(dot(n,normalize(lightDir)),0.0);
if (NdotL > 0.0) {
att = 1.0 / (gl_LightSource[2].constantAttenuation +
gl_LightSource[2].linearAttenuation * dist +
gl_LightSource[2].quadraticAttenuation * dist * dist);
color += att * (diffuse * NdotL + ambient);
halfV = normalize(halfVector);
NdotHV = max(dot(n,halfV),0.0);
color += att * gl_FrontMaterial.specular * gl_LightSource[2].specular * pow(NdotHV,gl_FrontMaterial.shininess);
}
gl_FragColor = color;
}
私はそれらを自分のコードで動作させようとしているだけで、何も書きませんでした。