Я только что включил отбраковку спины и замечаю странное поведение: когда все вершины моего треугольника находятся вне поля зрения, и 2 из них находятся позади меня (я думаю), треугольник исчезает.
Чтобы увидеть это, вот GIF.
Я подозреваю, что проекционная матрица меняет порядок двух вершин, когда они отстают от меня, и меняет намотку моего треугольника.
Но непонятно, почему треугольники исчезают, только если все вершины не видны ...
Как я могу обойти эту проблему, если это возможно?
Я разрабатываю на 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;
}
Буфер глубины просто настраивается путем его включения.