倒置 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的主要内容,如果未能解决你的问题,请参考以下文章

GDAL - 将图像扭曲到倒置的 y 轴坐标系(Apple MapKit)使图像倒置

停止相机中的Y轴反转

OPenGLopengl 64位 配置

Modern OpenGLOpenGL简介

OpenGLOpenGL中的Buffer的巧妙使用

如果 3d 视图的左右图像倒置,您会看到啥?