2016-09-04 4 views
1

Also habe ich mir auf youtube einen kleinen Intro-Kurs angeschaut, um die Grundlagen von OpenGL zu erlernen und lernte Dinge wie ein Dreieck und eine einfache Kamera-Klasse, etc. Ich wollte versuchen, eine Voxel-Engine zu entwickeln so offensichtlich war das erste, was ich mir vorstellen konnte, ein einfacher Würfel, den ich irgendwann replizieren konnte. Mein Problem ist jedoch, dass wenn ich gehe, um die Vertices und Dreiecke zu rendern, scheinen sie in einem Durcheinander zu sein, das nicht dem ähnelt, was ich hart in der Cube-Klasse codiert habe. Ich weiß, dass 0,0 die Mitte des Bildschirms ist; 1 in der x-Achse ist das Recht; -1 ist die linke; 1 in der y-Achse ist die Spitze und -1 ist die Unterseite. Wenn ich jedoch durch meine Ecken und Dreiecke zum Eckenpuffer sende, scheint es etwas völlig anderes zu machen. Es ist wahrscheinlich ein wirklich dummer Fehler von meiner Seite.Inverted X Axis OpenGL

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]))); 
} 

Die Funktion draw von meiner Mesh-Klasse geerbt

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); 
} 

Vertex und Dreieck structs in 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]; 
}; 

Kamerafunktionen

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); 
} 

Hinweis in der das Cube-Konstruktor bin ich nur ein Dreieck zu schaffen, die unten links, oben links sein sollten, oben rechts noch ist dies das Ergebnis:

The triangle isn't where I specified it

Ein weiterer Hinweis ist, dass meine Kamera Drehung ab und zu sein scheint. Wenn Sie die Y-Drehung ändern, wird sie tatsächlich auf der X-Achse gedreht und die X-Drehung ändert sich auf der Y-Achse.

Auch wenn jemand einen besseren Weg zum Erstellen und Rendern des Cubes hätte, wäre ich dankbar. Sobald ich das tun kann, werde ich wahrscheinlich in letsmakeavoxelengine Tutorials schauen.

Edit: Es fühlt sich an wie die x- und y-Achse invertiert sind. Ich könnte einfach alle meine Funktionen invertieren, um dem entgegenzuwirken, aber das ist irgendwie ein hacky Weg um es herum und es repariert immer noch nicht das zugrunde liegende Problem, das später mehr Ärger verursachen könnte.

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; 
}; 

Cube, Transformieren und Kamera-Anrufe in main.cpp:

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: 100% invertiert auf X-Achse. Neuer cube.cpp code:

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 

Ich habe einen Kommentar neben das neue Dreieck geschrieben, das Ihnen sagt, was die tatsächlichen resultierenden Dreieckspunkte waren. Das Dreieck, das ich eingestellt habe, sollte BottomRightFront, TopLeftBack, BottomLeftBack entsprechend dem Code sein. Ich werde auch einen Screenshot hinzufügen, wie es aussieht.

Triangle was supposed to be BottomRightFront, TopLeftBack, BottomLeftBack

+1

Können Sie ein vollständiges Beispiel bereitstellen, das kompiliert wird? Herkömmlich verwenden wir ein Rechtssystem, wenn also die X-Achse nach rechts zeigt und die Y-Achse nach oben zeigt, dann zeigt die Z-Achse nach hinten (zur Kamera hin); aber Ihr zNear und zFar sind positiv, und Ihr m_forwards ist (0 0 1) und nicht (0 0 -1); Ist das eine gute Sache? – Buster

+0

Ich denke, es muss eine gute Sache sein, denn wenn ich mir die Quelle aus den Videos ansehe, die ich gesehen habe, scheint es dasselbe zu sein. Und wie kann ich Ihnen das Projekt am besten zusenden? Google Drive? Quelle für die Kamera-Klasse aus den Videos hier btw: https://github.com/BennyQBD/ModernOpenGLTutorial/blob/master/camera.h – therealkf

+1

Hat Ihre "pos" eine negative z-Koordinate? Wenn nicht, dann ist das vielleicht das Problem. Aber vielleicht auch nicht, denn wenn das Problem genau das ist, dann würde ich erwarten, dass das Bild horizontal und vertikal gedreht wird. – Buster

Antwort

3

Ihre Beschreibung der X- und Y-Achsen klingt richtig, aber die Z-Achse scheint umgekehrt zu werden. Zum Beispiel gibt es in dem Code, den Sie gepostet haben, eine Variable m_forward, deren Wert (0, 0, 1) ist; dass könnte richtig sein, aber ich rufe diese Richtung normalerweise "rückwärts".

Herkömmlicherweise verwenden OpenGL-Programme ein rechtshändiges Koordinatensystem. Wenn X also nach rechts zeigt und Y nach oben zeigt, dann zeigt Z aus dem Bildschirm zum Auge. Wenn Sie dies im Hinterkopf behalten und Ihren Code überprüfen, indem Sie das Vorzeichen der Z-Komponente für jede Position und jeden Richtungsvektor überprüfen, sollten Sie den Fehler finden. Viel Glück!

+1

Perfekter Dank für die Hilfe! – therealkf

+1

Keine Sorge, du hast es wirklich selbst ausprobiert und es hat mir Spaß gemacht, dich zu engagieren. VIEL GLÜCK UND VIEL SPASS – Buster