Какие значения я должен отправить в матрицу нормализованного представления, чтобы прокрутка карты листов охватывала только плитку? - PullRequest
0 голосов
/ 23 сентября 2018

Это код, который создает матрицы проекции, вида и модели, которые отправляются в шейдер:

    GL.glEnable(GL.GL_BLEND)
    GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA)    

    arguments['texture'].bind()

    arguments['shader'].bind()
    arguments['shader'].uniformi('u_Texture', arguments['texture'].slot)

    proj = glm.ortho(0.0, float(arguments['screenWidth']), 0.0, float(arguments['screenHeight']), -1.0, 1.0)

    arguments['cameraXOffset'] = (float(arguments['cameraXOffset']) / 32) / float(arguments['screenWidth'])
    arguments['cameraYOffset'] = (- float(arguments['cameraYOffset']) / 32) / float(arguments['screenHeight'])

    print('{}, {}'.format(arguments['cameraXOffset'], arguments['cameraYOffset']))

    view = glm.translate(glm.mat4(1.0), glm.vec3(float(arguments['cameraXOffset']), float(arguments['cameraYOffset']), 0.0))

    model = glm.translate(glm.mat4(1.0), glm.vec3(0.0, 0.0, 0.0))

    arguments['shader'].uniform_matrixf('u_Proj', proj)
    arguments['shader'].uniform_matrixf('u_View', view)
    arguments['shader'].uniform_matrixf('u_Model', model)

Матрица проекции изменяется от 0,0 до ширины экрана и от 0,0 до высоты экрана.Это позволяет мне использовать фактическую ширину в пикселях плиток (32x32) при определении вершинных перемещений.Кроме того, когда пользователь нажимает клавиши wasd, камера накапливает смещения, которые охватывают ширину или высоту плитки (всегда 32).К сожалению, чтобы отразить это смещение в матрице вида, мне кажется, что мне нужно его нормализовать, и я не могу понять, как это сделать, чтобы одно движение в любом кардинальном направлении охватывало одну плитку и ничего более.Он постоянно накапливает ошибку, поэтому в конце карты в любом направлении он показывает полосу фона (в данном случае белый).

Это самая важная часть, которая определяет, сколько она будет прокручивать с заданными смещениями камеры:

    arguments['cameraXOffset'] = (float(arguments['cameraXOffset']) / 32) / float(arguments['screenWidth'])
    arguments['cameraYOffset'] = (- float(arguments['cameraYOffset']) / 32) / float(arguments['screenHeight'])

Может кто-нибудь из вас выяснить, если эта "нормализация" радиматрица вида правильная?Или это вопрос округления?В таком случае, могу ли я как-то решить это?

Вершинный шейдер:

#version 330 core 

layout(location = 0) in vec3 position;
layout(location = 1) in vec4 color; 
layout(location = 2) in vec2 texCoord;

out vec4 v_Color;
out vec2 v_TexCoord;

uniform mat4 u_Proj;
uniform mat4 u_View;
uniform mat4 u_Model;

void main()
{ 
    gl_Position = u_Model * u_View * u_Proj * vec4(position, 1.0);
    v_TexCoord = texCoord; v_Color = color;
}  

ЗАКЛЮЧИТЕЛЬНАЯ ВЕРСИЯ: Решено.Как упоминалось комментатором, пришлось изменить эту строку в вершинном шейдере:

gl_Position = u_Model * u_View * u_Proj * vec4(position, 1.0);

на:

gl_Position = u_Proj * u_View * u_Model * vec4(position, 1.0);

Окончательная версия кода, которая в итоге позволяет пользователю прокручиватьровно один тайл:

arguments['texture'].bind()

arguments['shader'].bind()
arguments['shader'].uniformi('u_Texture', arguments['texture'].slot)

proj = glm.ortho(0.0, float(arguments['screenWidth']), 0.0, float(arguments['screenHeight']), -1.0, 1.0)

arguments['cameraXOffset'] = (float(arguments['cameraXOffset']) / 32) / arguments['screenWidth']
arguments['cameraYOffset'] = (float(-arguments['cameraYOffset']) / 32) / arguments['screenHeight']

view = glm.translate(glm.mat4(1.0), glm.vec3(float(arguments['cameraXOffset']), float(arguments['cameraYOffset']), 0.0))

 model = glm.translate(glm.mat4(1.0), glm.vec3(0.0, 0.0, 0.0))

 arguments['shader'].uniform_matrixf('u_Proj', proj)
 arguments['shader'].uniform_matrixf('u_View', view)
 arguments['shader'].uniform_matrixf('u_Model', model)

1 Ответ

0 голосов
/ 23 сентября 2018

Вам необходимо изменить порядок матриц при преобразовании координаты вершины в координату пространства клипа:

gl_Position = u_Proj * u_View * u_Model * vec4(position, 1.0);

См. Программирование GLSL / Операции с вектором и матрицей :

Кроме того, * -оператор может использоваться для матрично-векторных произведений соответствующего измерения, например:

vec2 v = vec2(10., 20.);
mat2 m = mat2(1., 2.,  3., 4.);
vec2 w = m * v; // = vec2(1. * 10. + 3. * 20., 2. * 10. + 4. * 20.)

Обратите внимание, что вектор должен быть умножен наматрица справа.

Если вектор умножается на матрицу слева, результат соответствует умножению вектора столбца на транспонированную матрицу справа.Это соответствует умножению вектора столбца на транспонированную матрицу справа:
Таким образом, умножение вектора слева на матрицу соответствует умножению его справа на транспонированную матрицу:

vec2 v = vec2(10., 20.);
mat2 m = mat2(1., 2.,  3., 4.);
vec2 w = v * m; // = vec2(1. * 10. + 2. * 20., 3. * 10. + 4. * 20.)

Это также относится к самому умножению матриц.Первая матрица, которая должна быть применена к вектору, должна быть самой правой матрицей, а последняя матрица - самой левой в ряду сцепленных матриц.

...