倒置 X 轴 OpenGL
Posted
技术标签:
【中文标题】倒置 X 轴 OpenGL【英文标题】:Inverted X Axis OpenGL 【发布时间】:2016-09-04 21:59:40 【问题描述】:所以我在 youtube 上观看了一些介绍性课程,以学习 OpenGL 的基础知识,并学习了制作三角形和简单的相机类等内容。我一直想尝试制作一个体素引擎,显然是第一个我想做的是一个简单的立方体,我最终可以复制它。我的问题是,当我去渲染顶点和三角形时,它们似乎一团糟,与我在立方体类中硬编码的内容不同。我知道 0,0 是屏幕的中心; x轴上的1是右边; -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])));
从我的网格类继承的绘制函数
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 轴是倒置的。我可以反转我所有的函数来解决这个问题,但这是一种解决方法,它仍然不能解决潜在的问题,这可能会在以后造成更多麻烦。
Edit2: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 轴指向后方(朝向相机);但是你的 zNear 和 zFar 是正数,你的 m_forwards 是 (0 0 1) 而不是 (0 0 -1);这是glm的事情吗? 您的“pos”是否有负 z 坐标?如果不是,那么也许这就是问题所在。但话又说回来,也许不是,因为如果问题就是这样,那么我希望图像水平翻转 和 垂直翻转。 对不起,我之前没有注意到你的问题,关于发送项目的最佳方式。理想情况下,所有代码都在问题中,但我明白“OpenGL”和“小而完整的示例”不能很好地结合在一起!我希望我知道 *** 的推荐解决方案是什么。 Camera::GetViewProjection 中对 glm::lookAt 的调用看起来很可疑;特别是你有“中心”(第二个参数)在“眼睛”(第一个参数),因为“m_forwards”指向后面。 我的荣幸!尝试用 (0 0 0) 表示“眼睛”,m_pos 表示“中心”,使用 (0 1 0) 表示“向上”? 【参考方案1】:您对 X 轴和 Y 轴的描述听起来不错,但 Z 轴似乎颠倒了。例如,在您发布的代码中有一个变量m_forward
,其值为 (0, 0, 1); 可能是对的,但我通常称这个方向为“向后”。
按照惯例,OpenGL 程序使用右手坐标系,因此如果 X 指向右侧且 Y 指向上方,则 Z 指向屏幕外,朝向眼睛。如果您牢记这一点并查看您的代码,检查每个位置和方向向量的 Z 分量的符号,您应该会发现错误。祝你好运!
【讨论】:
以上是关于倒置 X 轴 OpenGL的主要内容,如果未能解决你的问题,请参考以下文章