裏面カリングを有効にしたところ、奇妙な動作に気づきました。三角形のすべての頂点がビューの外側にあり、そのうちの2つが背後にあると(私はそうです)、三角形が消えます。
それを見るには、ここにGIFがあります。
投影行列が2つの頂点の順序を逆にし、それらが私の後ろに落ちて、三角形の曲がり方を変えたのではないかと思います。
しかし、すべての頂点が見えない場合にのみ三角形が消える理由は不明です...
可能であれば、この問題を回避するにはどうすればよいですか?
それが問題ならLinuxで開発します。
更新:
裏面カリングによるものではない可能性が指摘されています。無効にしたので、実際に再現できます。立方体は20×20で、垂直視野は90°です。垂直方向の見かけのサイズは、ウィンドウをほぼ埋めます。
更新2:
では、コードの関連部分を投稿します。投影とビューマトリックスは、自分の関数を使用して設定されます。
void createViewMatrix(
GLfloat matrix[16],
const Vector3 *forward,
const Vector3 *up,
const Vector3 *pos
)
{
/* Setting up perpendicular axes */
Vector3 rright;
Vector3 rup = *up;
Vector3 rforward = *forward;
vbonorm(&rright, &rup, &rforward); /* Orthonormalization (right is computed from scratch) */
/* Filling the matrix */
matrix[0] = rright.x;
matrix[1] = rup.x;
matrix[2] = -rforward.x;
matrix[3] = 0;
matrix[4] = rright.y;
matrix[5] = rup.y;
matrix[6] = -rforward.y;
matrix[7] = 0;
matrix[8] = rright.z;
matrix[9] = rup.z;
matrix[10] = -rforward.z;
matrix[11] = 0;
matrix[12] = -vdp(pos, &rright);
matrix[13] = -vdp(pos, &rup);
matrix[14] = vdp(pos, &rforward);
matrix[15] = 1;
}
void createProjectionMatrix(
GLfloat matrix[16],
GLfloat vfov,
GLfloat aspect,
GLfloat near,
GLfloat far
)
{
GLfloat vfovtan = 1 / tan(RAD(vfov * 0.5));
memset(matrix, 0, sizeof(*matrix) * 16);
matrix[0] = vfovtan / aspect;
matrix[5] = vfovtan;
matrix[10] = (near+far)/(near-far);
matrix[11] = -1;
matrix[14] = (2*near*far)/(near-far);
}
この呼び出しで設定された射影行列:
createProjectionMatrix(projMatrix, VERTICAL_FOV, ASPECT_RATIO, Z_NEAR, 10000);
(VERTICAL_FOV = 90、ASPECT_RATIO = 4.0 / 3、Z_NEAR = 1)
レベル描画は単純です:
void drawStuff()
{
GLfloat projectView[16];
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
createViewMatrix(viewMatrix, &camera.forward, &camera.up, &camera.pos);
multiplyMatrix(projectView, viewMatrix, projMatrix); /*< Row mayor multiplication. */
glUniformMatrix4fv(renderingMatrixId, 1, GL_FALSE, projectView);
bailOnGlError(__FILE__, __LINE__);
renderLevel(&testLevel);
}
キューブは壁ごとにレンダリングされます(これを最適化することは別の話になります):
for (j = 0; j < 6; j++)
{
glBindTexture(GL_TEXTURE_2D, cube->wallTextureIds[j]);
bailOnGlError(__FILE__, __LINE__);
glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_INT, (void*)(sizeof(GLuint) * 4 * j));
bailOnGlError(__FILE__, __LINE__);
glUniform4f(extraColorId, 1, 1, 1, 1);
bailOnGlError(__FILE__, __LINE__);
}
頂点シェーダー:
#version 110
attribute vec3 position;
attribute vec3 color;
attribute vec2 texCoord;
varying vec4 f_color;
varying vec2 f_texCoord;
uniform mat4 renderingMatrix;
void main()
{
gl_Position = renderingMatrix * vec4(position, 1);
f_color = vec4(color, 1);
f_texCoord = texCoord;
}
フラグメントシェーダー:
#version 110
varying vec4 f_color;
varying vec2 f_texCoord;
uniform sampler2D tex;
uniform vec4 extraColor;
void main()
{
gl_FragColor = texture2D(tex, f_texCoord) * vec4(f_color) * extraColor;
}
深度バッファーは、有効にすることで簡単に設定できます。