Я создаю небольшой игровой движок, в котором я хочу рисовать вещи, используя OpenGL. Я абстрагировал все объекты OpenGL в классы (Buffers, VertexArrays, Shaders, Programs ...). Все работало нормально, пока я не добрался до 3D-рендеринга. Я реализовал свои собственные матрицы и векторы (я не использовал как glm), и когда я умножаю свою позицию вершины в шейдере на любую матрицу, координата z переворачивается (z = -z). Я даже пытался с матрицей идентичности. Вот вершинный шейдер:
#version 330 core
layout(location = 0) in vec4 i_pos;
layout(location = 1) in vec4 i_color;
out vec4 p_color;
uniform mat4 u_MVP;
uniform vec4 u_pos;
void main()
{
gl_Position = u_MVP * (i_pos + u_pos);
p_color = i_color;
}
Я использовал униформу u_Pos
только для отладки. И здесь я установил форму:
void Frame() override
{
deltaTime = timer.Reset();
if (Input::GetKey(Key::W).value == KeyDown) pos.z += deltaTime;
if (Input::GetKey(Key::S).value == KeyDown) pos.z -= deltaTime;
//mat4f(1.0f) creates a identity matrix
shaderSelection.SetUniform("u_MVP", mat4f(1.0f));
shaderSelection.SetUniform("u_pos", vec4f(pos));
ren.DrawTriangles(vertexArray, indexBuffer, shaderSelection);
}
Хотя я уверен, что нет ничего с матричной структурой, вот она:
template<typename T = float, int sizeX = 4, int sizeY = 4>
struct BLAZE_API mat
{
private:
T v[sizeY][sizeX];
public:
mat()
{
for (unsigned i = 0; i < sizeX * sizeY; i++)
((T*)v)[i] = 0;
}
mat(T* ptr, bool transpose = false)
{
if (transpose)
for (unsigned i = 0; i < sizeX * sizeY; i++)
((T*)v)[i] = ptr[i];
else
for (unsigned i = 0; i < sizeX * sizeY; i++)
((T*)v)[i] = ptr[i % sizeY * sizeX + i / sizeY];
}
mat(T n)
{
for (int x = 0; x < sizeX; x++)
for (int y = 0; y < sizeY; y++)
if (x == y)
operator[](x)[y] = n;
else
operator[](x)[y] = 0;
}
mat(const mat<T, sizeX, sizeY>& mat)
{
for (int x = 0; x < sizeX; x++)
for (int y = 0; y < sizeY; y++)
v[x][y] = mat[x][y];
}
inline T* operator[] (unsigned i) const { return (T*)(v[i]); }
inline void operator= (const mat<T, sizeX, sizeY>& mat)
{
for (int x = 0; x < sizeX; x++)
for (int y = 0; y < sizeY; y++)
v[x][y] = mat[x][y];
}
};
И SetUniform
делает это:
glUniformMatrix4fv( ... , 1, GL_FALSE, m[0]);
Я сделал матричную структуру такой, чтобы мне не приходилось использовать GL_TRUE
для transpose
параметра в glUniformMatrix4fv
. Я уверен, что не моя матричная реализация инвертирует координату z. Это похоже на то, что камера смотрит в направлении -Z, но когда я перемещаю объект в направлении + X, он перемещается также на + X на экране (также относится к направлению Y), чего не должно быть, если камера обращена -Z. Это должно произойти, если я могу это изменить?