倒 X 轴 OpenGL
Inverted X Axis OpenGL
所以我在 youtube 上观看了一些介绍性课程以学习 OpenGL 的基础知识并学习了制作三角形和简单相机等内容 class 等。我想尝试制作一个体素引擎很明显,我想到的第一件事就是制作一个我最终可以复制的简单立方体。我的问题是,当我渲染顶点和三角形时,它们看起来一团糟,与我在立方体 class 中硬编码的内容不同。我知道0,0是屏幕的中心; 1在x轴是右边; -1 是左边; y 轴中的 1 是顶部,-1 是底部。然而,当我将顶点和三角形发送到顶点缓冲区时,它似乎在做一些完全不同的事情。这很可能是我的一个非常愚蠢的错误。
Cube::Cube()
{
m_vertices[0] = Vertex(glm::vec3(-0.5, -0.5, 0));
m_vertices[1] = Vertex(glm::vec3(-0.5, 0.5, 0));
m_vertices[2] = Vertex(glm::vec3(0.5, 0.5, 0));
m_vertices[3] = Vertex(glm::vec3(0.5, -0.5, 0));
m_vertices[4] = Vertex(glm::vec3(-0.5, -0.5, 1));
m_vertices[5] = Vertex(glm::vec3(-0.5, 0.5, 1));
m_vertices[6] = Vertex(glm::vec3(0.5, 0.5, 1));
m_vertices[7] = Vertex(glm::vec3(0.5, -0.5, 1));
m_triangles[0] = Triangle(0, 1, 2); //Front
//m_triangles[1] = Triangle(0, 2, 3); //Front
//m_triangles[2] = Triangle(1, 5, 6); //Top
//m_triangles[3] = Triangle(1, 6, 2); //Top
//m_triangles[4] = Triangle(3, 5, 4); //Left
//m_triangles[5] = Triangle(3, 5, 4); //Left
//m_triangles[6] = Triangle(3, 2, 7); //Right
//m_triangles[7] = Triangle(3, 3, 7); //Right
//m_triangles[8] = Triangle(7, 6, 4); //Back
//m_triangles[9] = Triangle(5, 6, 7); //Back
//m_triangles[10] = Triangle(0, 4, 7); //Bottom
//m_triangles[11] = Triangle(0, 3, 7); //Bottom
}
void Cube::Render()
{
Draw(m_vertices, sizeof(m_vertices) / sizeof(m_vertices[0]), m_triangles, (sizeof(m_triangles) / sizeof(m_triangles[0])));
}
从我的网格继承的绘制函数class
void Mesh::Draw(Vertex* vertices, unsigned int numVertices, Triangle* triangles, unsigned int numTriangles)
{
//Array of indices
std::vector<unsigned int> indices;
for (int i = 0; i < numTriangles; i++)
{
indices.push_back(triangles[i].GetTriangle()[0]);
indices.push_back(triangles[i].GetTriangle()[1]);
indices.push_back(triangles[i].GetTriangle()[2]);
}
//How many vertices to draw
m_drawCount = indices.size();
//Generate and bind vertex array
glGenVertexArrays(1, &m_vertexArrayObject);
glBindVertexArray(m_vertexArrayObject);
//Generate and bind buffers
glGenBuffers(NUM_BUFFERS, m_vertexArrayBuffers);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexArrayBuffers[POSITION_VB]);
//Write vertex data to the buffer
glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(vertices[0]), &vertices[0], GL_STATIC_DRAW);
//Only one attribute for the vertex data
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vertexArrayBuffers[INDEX_VB]);
//Write vertex data to the buffer
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0]) * indices.size(), &indices[0], GL_STATIC_DRAW);
//Unbind vertex array
glBindVertexArray(0);
glBindVertexArray(m_vertexArrayObject);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glDrawElements(GL_TRIANGLES, m_drawCount, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
mesh.h
中的顶点和三角形结构
struct Vertex
{
public:
//Constructor
Vertex()
{
}
//Constructor
Vertex(const glm::vec3& pos)
{
//Set vertex position
this->m_pos = pos;
}
protected:
private:
//Vertex position
glm::vec3 m_pos;
};
struct Triangle
{
public:
//Constructor
Triangle()
{
}
//Constructor
Triangle(int point1, int point2, int point3)
{
SetTriangle(point1, point2, point3);
}
int* GetTriangle()
{
return m_points;
}
void SetTriangle(int point1, int point2, int point3)
{
m_points[0] = point1;
m_points[1] = point2;
m_points[2] = point3;
}
protected:
private:
int m_points[3];
};
相机功能
Camera::Camera(const glm::vec3 pos, float fov, float aspect, float zNear, float zFar)
{
m_perspectiveMatrix = glm::perspective(fov, aspect, zNear, zFar);
m_pos = pos;
m_forward = glm::vec3(0, 0, 1);
m_up = glm::vec3(0, 1, 0);
}
glm::mat4 Camera::GetViewProjection() const
{
return m_perspectiveMatrix * glm::lookAt(m_pos, m_pos + m_forward, m_up);
}
请注意,在立方体构造函数中,我只创建了一个三角形,它应该位于左下角、左上角、右上角,但这是结果:
另一个注意事项是我的相机旋转似乎也关闭了。改变 y 旋转实际上是在 x 轴上旋转,改变 x 旋转是在 y 轴上旋转。
此外,如果有人有更好的创建和渲染立方体的方法,我将不胜感激。一旦我能做到这一点,我很可能会查看 letsmakeavoxelengine 教程。
编辑:感觉x轴和y轴倒置了。我可以反转我所有的函数来解决这个问题,但这是一种绕过它的 hacky 方法,它仍然没有解决潜在的问题,这可能会在以后造成更多麻烦。
编辑 2:Transform.h
#pragma once
#include <glm\glm.hpp>
#include <glm\gtx\transform.hpp>
#include "Camera.h"
struct Transform
{
public:
//Constructor
Transform(const glm::vec3& pos = glm::vec3(), const glm::vec3& rot = glm::vec3(), const glm::vec3& scale = glm::vec3(1.0f, 1.0f, 1.0f))
{
this->m_pos = pos;
this->m_rot = rot;
this->m_scale = scale;
}
//Get the model matrix
inline glm::mat4 GetModelMatrix() const
{
//Create all the transform matrices
//Position matrix
glm::mat4 posMatrix = glm::translate(m_pos);
//Scale matrix
glm::mat4 scaleMatrix = glm::scale(m_scale);
//Rotation matrix X
glm::mat4 rotXMatrix = glm::rotate(m_rot.x, glm::vec3(1.0f, 0.0f, 0.0f));
//Rotation matrix Y
glm::mat4 rotYMatrix = glm::rotate(m_rot.y, glm::vec3(0.0f, 1.0f, 0.0f));
//Rotation matrix Z
glm::mat4 rotZMatrix = glm::rotate(m_rot.z, glm::vec3(0.0f, 0.0f, 1.0f));
//Combined rotation matrix
glm::mat4 rotMatrix = rotXMatrix * rotYMatrix * rotZMatrix;
return posMatrix * rotMatrix * scaleMatrix;
}
inline glm::mat4 GetMVP(const Camera& camera) const
{
glm::mat4 ViewProjection = camera.GetViewProjection();
glm::mat4 ModelMatrix = GetModelMatrix();
return ViewProjection * ModelMatrix;//camera.GetViewProjection() * GetModel();
}
//Get position
inline glm::vec3* GetPosition() { return &m_pos; }
//Get rotation
inline glm::vec3* GetRotation() { return &m_rot; }
//Get scale
inline glm::vec3* GetScale() { return &m_scale; }
//Set Position
inline void SetPosition(const glm::vec3& pos) { this->m_pos = pos; }
//Set Rotation
inline void SetRotation(const glm::vec3& rot) { this->m_rot = rot; }
//Set Scale
inline void SetScale(const glm::vec3& scale) { this->m_scale = scale; }
private:
//Transform position
glm::vec3 m_pos;
//Transform rotation
glm::vec3 m_rot;
//Transform scale
glm::vec3 m_scale;
};
main.cpp 中的 Cube、Transform 和 Camera 调用:
Cube cube;
Transform transform;
Camera camera(glm::vec3(0.0f, 0.0f, -3.0f), 70.0f, (float)display.GetWidth()/(float)display.GetHeight(), 0.01f, 100.0f);
Edit3:X 轴 100% 反转。新 cube.cpp 代码:
m_vertices[0] = Vertex(glm::vec3(-0.5, -0.5, 0)); //BottomLeftFront
m_vertices[1] = Vertex(glm::vec3(-0.5, 0.5, 0)); //TopLeftFront
m_vertices[2] = Vertex(glm::vec3(0.5, 0.5, 0)); //TopRightFront
m_vertices[3] = Vertex(glm::vec3(0.5, -0.5, 0)); //BottomRightFront
m_vertices[4] = Vertex(glm::vec3(-0.5, -0.5, 1)); //BottomLeftBack
m_vertices[5] = Vertex(glm::vec3(-0.5, 0.5, 1)); //TopLeftBack
m_vertices[6] = Vertex(glm::vec3(0.5, 0.5, 1)); //TopRightBack
m_vertices[7] = Vertex(glm::vec3(0.5, -0.5, 1)); //BottomRightBack
m_triangles[0] = Triangle(0, 1, 2); //Front
m_triangles[1] = Triangle(0, 2, 3); //Front
//m_triangles[2] = Triangle(1, 5, 6); //Top
//m_triangles[3] = Triangle(1, 6, 2); //Top
m_triangles[4] = Triangle(3, 5, 4); //Left //BottomLeftFront, TopRightBack, BottomRightBack
//m_triangles[5] = Triangle(3, 5, 4); //Left
//m_triangles[6] = Triangle(3, 2, 7); //Right
//m_triangles[7] = Triangle(3, 3, 7); //Right
//m_triangles[8] = Triangle(7, 6, 4); //Back
//m_triangles[9] = Triangle(5, 6, 7); //Back
//m_triangles[10] = Triangle(0, 4, 7); //Bottom
//m_triangles[11] = Triangle(0, 3, 7); //Bottom
我在新三角形旁边添加了注释,告诉您实际生成的三角形点是什么。根据代码,我设置的三角形应该是BottomRightFront、TopLeftBack、BottomLeftBack。我还将添加它的外观截图。
你对X轴和Y轴的描述听起来是对的,但是Z轴好像是反的。例如,在您发布的代码中有一个变量 m_forward
,其值为 (0, 0, 1); 可能是对的,但我通常称那个方向为"backwards"。
传统上,OpenGL 程序使用右手坐标系,因此如果 X 指向右,Y 指向上,则 Z 指向屏幕外,朝向眼睛。如果您牢记这一点并检查您的代码,检查每个位置和方向向量的 Z 分量的符号,您应该会发现错误。祝你好运!
所以我在 youtube 上观看了一些介绍性课程以学习 OpenGL 的基础知识并学习了制作三角形和简单相机等内容 class 等。我想尝试制作一个体素引擎很明显,我想到的第一件事就是制作一个我最终可以复制的简单立方体。我的问题是,当我渲染顶点和三角形时,它们看起来一团糟,与我在立方体 class 中硬编码的内容不同。我知道0,0是屏幕的中心; 1在x轴是右边; -1 是左边; y 轴中的 1 是顶部,-1 是底部。然而,当我将顶点和三角形发送到顶点缓冲区时,它似乎在做一些完全不同的事情。这很可能是我的一个非常愚蠢的错误。
Cube::Cube()
{
m_vertices[0] = Vertex(glm::vec3(-0.5, -0.5, 0));
m_vertices[1] = Vertex(glm::vec3(-0.5, 0.5, 0));
m_vertices[2] = Vertex(glm::vec3(0.5, 0.5, 0));
m_vertices[3] = Vertex(glm::vec3(0.5, -0.5, 0));
m_vertices[4] = Vertex(glm::vec3(-0.5, -0.5, 1));
m_vertices[5] = Vertex(glm::vec3(-0.5, 0.5, 1));
m_vertices[6] = Vertex(glm::vec3(0.5, 0.5, 1));
m_vertices[7] = Vertex(glm::vec3(0.5, -0.5, 1));
m_triangles[0] = Triangle(0, 1, 2); //Front
//m_triangles[1] = Triangle(0, 2, 3); //Front
//m_triangles[2] = Triangle(1, 5, 6); //Top
//m_triangles[3] = Triangle(1, 6, 2); //Top
//m_triangles[4] = Triangle(3, 5, 4); //Left
//m_triangles[5] = Triangle(3, 5, 4); //Left
//m_triangles[6] = Triangle(3, 2, 7); //Right
//m_triangles[7] = Triangle(3, 3, 7); //Right
//m_triangles[8] = Triangle(7, 6, 4); //Back
//m_triangles[9] = Triangle(5, 6, 7); //Back
//m_triangles[10] = Triangle(0, 4, 7); //Bottom
//m_triangles[11] = Triangle(0, 3, 7); //Bottom
}
void Cube::Render()
{
Draw(m_vertices, sizeof(m_vertices) / sizeof(m_vertices[0]), m_triangles, (sizeof(m_triangles) / sizeof(m_triangles[0])));
}
从我的网格继承的绘制函数class
void Mesh::Draw(Vertex* vertices, unsigned int numVertices, Triangle* triangles, unsigned int numTriangles)
{
//Array of indices
std::vector<unsigned int> indices;
for (int i = 0; i < numTriangles; i++)
{
indices.push_back(triangles[i].GetTriangle()[0]);
indices.push_back(triangles[i].GetTriangle()[1]);
indices.push_back(triangles[i].GetTriangle()[2]);
}
//How many vertices to draw
m_drawCount = indices.size();
//Generate and bind vertex array
glGenVertexArrays(1, &m_vertexArrayObject);
glBindVertexArray(m_vertexArrayObject);
//Generate and bind buffers
glGenBuffers(NUM_BUFFERS, m_vertexArrayBuffers);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexArrayBuffers[POSITION_VB]);
//Write vertex data to the buffer
glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(vertices[0]), &vertices[0], GL_STATIC_DRAW);
//Only one attribute for the vertex data
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vertexArrayBuffers[INDEX_VB]);
//Write vertex data to the buffer
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0]) * indices.size(), &indices[0], GL_STATIC_DRAW);
//Unbind vertex array
glBindVertexArray(0);
glBindVertexArray(m_vertexArrayObject);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glDrawElements(GL_TRIANGLES, m_drawCount, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
mesh.h
中的顶点和三角形结构struct Vertex
{
public:
//Constructor
Vertex()
{
}
//Constructor
Vertex(const glm::vec3& pos)
{
//Set vertex position
this->m_pos = pos;
}
protected:
private:
//Vertex position
glm::vec3 m_pos;
};
struct Triangle
{
public:
//Constructor
Triangle()
{
}
//Constructor
Triangle(int point1, int point2, int point3)
{
SetTriangle(point1, point2, point3);
}
int* GetTriangle()
{
return m_points;
}
void SetTriangle(int point1, int point2, int point3)
{
m_points[0] = point1;
m_points[1] = point2;
m_points[2] = point3;
}
protected:
private:
int m_points[3];
};
相机功能
Camera::Camera(const glm::vec3 pos, float fov, float aspect, float zNear, float zFar)
{
m_perspectiveMatrix = glm::perspective(fov, aspect, zNear, zFar);
m_pos = pos;
m_forward = glm::vec3(0, 0, 1);
m_up = glm::vec3(0, 1, 0);
}
glm::mat4 Camera::GetViewProjection() const
{
return m_perspectiveMatrix * glm::lookAt(m_pos, m_pos + m_forward, m_up);
}
请注意,在立方体构造函数中,我只创建了一个三角形,它应该位于左下角、左上角、右上角,但这是结果:
另一个注意事项是我的相机旋转似乎也关闭了。改变 y 旋转实际上是在 x 轴上旋转,改变 x 旋转是在 y 轴上旋转。
此外,如果有人有更好的创建和渲染立方体的方法,我将不胜感激。一旦我能做到这一点,我很可能会查看 letsmakeavoxelengine 教程。
编辑:感觉x轴和y轴倒置了。我可以反转我所有的函数来解决这个问题,但这是一种绕过它的 hacky 方法,它仍然没有解决潜在的问题,这可能会在以后造成更多麻烦。
编辑 2:Transform.h
#pragma once
#include <glm\glm.hpp>
#include <glm\gtx\transform.hpp>
#include "Camera.h"
struct Transform
{
public:
//Constructor
Transform(const glm::vec3& pos = glm::vec3(), const glm::vec3& rot = glm::vec3(), const glm::vec3& scale = glm::vec3(1.0f, 1.0f, 1.0f))
{
this->m_pos = pos;
this->m_rot = rot;
this->m_scale = scale;
}
//Get the model matrix
inline glm::mat4 GetModelMatrix() const
{
//Create all the transform matrices
//Position matrix
glm::mat4 posMatrix = glm::translate(m_pos);
//Scale matrix
glm::mat4 scaleMatrix = glm::scale(m_scale);
//Rotation matrix X
glm::mat4 rotXMatrix = glm::rotate(m_rot.x, glm::vec3(1.0f, 0.0f, 0.0f));
//Rotation matrix Y
glm::mat4 rotYMatrix = glm::rotate(m_rot.y, glm::vec3(0.0f, 1.0f, 0.0f));
//Rotation matrix Z
glm::mat4 rotZMatrix = glm::rotate(m_rot.z, glm::vec3(0.0f, 0.0f, 1.0f));
//Combined rotation matrix
glm::mat4 rotMatrix = rotXMatrix * rotYMatrix * rotZMatrix;
return posMatrix * rotMatrix * scaleMatrix;
}
inline glm::mat4 GetMVP(const Camera& camera) const
{
glm::mat4 ViewProjection = camera.GetViewProjection();
glm::mat4 ModelMatrix = GetModelMatrix();
return ViewProjection * ModelMatrix;//camera.GetViewProjection() * GetModel();
}
//Get position
inline glm::vec3* GetPosition() { return &m_pos; }
//Get rotation
inline glm::vec3* GetRotation() { return &m_rot; }
//Get scale
inline glm::vec3* GetScale() { return &m_scale; }
//Set Position
inline void SetPosition(const glm::vec3& pos) { this->m_pos = pos; }
//Set Rotation
inline void SetRotation(const glm::vec3& rot) { this->m_rot = rot; }
//Set Scale
inline void SetScale(const glm::vec3& scale) { this->m_scale = scale; }
private:
//Transform position
glm::vec3 m_pos;
//Transform rotation
glm::vec3 m_rot;
//Transform scale
glm::vec3 m_scale;
};
main.cpp 中的 Cube、Transform 和 Camera 调用:
Cube cube;
Transform transform;
Camera camera(glm::vec3(0.0f, 0.0f, -3.0f), 70.0f, (float)display.GetWidth()/(float)display.GetHeight(), 0.01f, 100.0f);
Edit3:X 轴 100% 反转。新 cube.cpp 代码:
m_vertices[0] = Vertex(glm::vec3(-0.5, -0.5, 0)); //BottomLeftFront
m_vertices[1] = Vertex(glm::vec3(-0.5, 0.5, 0)); //TopLeftFront
m_vertices[2] = Vertex(glm::vec3(0.5, 0.5, 0)); //TopRightFront
m_vertices[3] = Vertex(glm::vec3(0.5, -0.5, 0)); //BottomRightFront
m_vertices[4] = Vertex(glm::vec3(-0.5, -0.5, 1)); //BottomLeftBack
m_vertices[5] = Vertex(glm::vec3(-0.5, 0.5, 1)); //TopLeftBack
m_vertices[6] = Vertex(glm::vec3(0.5, 0.5, 1)); //TopRightBack
m_vertices[7] = Vertex(glm::vec3(0.5, -0.5, 1)); //BottomRightBack
m_triangles[0] = Triangle(0, 1, 2); //Front
m_triangles[1] = Triangle(0, 2, 3); //Front
//m_triangles[2] = Triangle(1, 5, 6); //Top
//m_triangles[3] = Triangle(1, 6, 2); //Top
m_triangles[4] = Triangle(3, 5, 4); //Left //BottomLeftFront, TopRightBack, BottomRightBack
//m_triangles[5] = Triangle(3, 5, 4); //Left
//m_triangles[6] = Triangle(3, 2, 7); //Right
//m_triangles[7] = Triangle(3, 3, 7); //Right
//m_triangles[8] = Triangle(7, 6, 4); //Back
//m_triangles[9] = Triangle(5, 6, 7); //Back
//m_triangles[10] = Triangle(0, 4, 7); //Bottom
//m_triangles[11] = Triangle(0, 3, 7); //Bottom
我在新三角形旁边添加了注释,告诉您实际生成的三角形点是什么。根据代码,我设置的三角形应该是BottomRightFront、TopLeftBack、BottomLeftBack。我还将添加它的外观截图。
你对X轴和Y轴的描述听起来是对的,但是Z轴好像是反的。例如,在您发布的代码中有一个变量 m_forward
,其值为 (0, 0, 1); 可能是对的,但我通常称那个方向为"backwards"。
传统上,OpenGL 程序使用右手坐标系,因此如果 X 指向右,Y 指向上,则 Z 指向屏幕外,朝向眼睛。如果您牢记这一点并检查您的代码,检查每个位置和方向向量的 Z 分量的符号,您应该会发现错误。祝你好运!