简体   繁体   中英

OpenGL C++ abstracting and problem with vertex drawing

I'm learning OpenGL from https://learnopengl.com/Getting-started/OpenGL , and I'm following the first tutorials and trying to abstract OpenGL stuff into classes.I'll post the code of what I did.

Creating a window works fine but drawing a mesh shows nothing. Also, the code for Shader class is located in here: https://learnopengl.com/code_viewer_gh.php?code=includes/learnopengl/shader_s.h

(Worth notice: I don't get any error in the shader class)

Now for my code:

Display.cpp:

    Display::Display(int width, int height, const std::string &title) {

    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    m_window = glfwCreateWindow(width, height, "LearnOpenGL", nullptr, nullptr);

    if (m_window == NULL) {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        exit(-1);
    }

    glfwMakeContextCurrent(m_window);
    glewInit();


    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glCullFace(GL_BACK);
}

Display::~Display() {
    glfwDestroyWindow(m_window);
    glfwTerminate();
}

void Display::Clear(float r, float g, float b, float a) {
    glClearColor(r, g, b, a);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

void Display::SwapBuffers() {
    glfwSwapBuffers(m_window);
}

bool Display::ShouldClose() {
    return glfwWindowShouldClose(m_window);
}

void Display::SetClose() {
    glfwSetWindowShouldClose(m_window, GL_TRUE);
}

void Display::ProcessInput() {
    if (glfwGetKey(m_window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
        SetClose();
    }
}

Vertex class:

class Vertex {
    glm::vec3 pos;
public:
    Vertex(const glm::vec3 &pos) {
        this->pos = pos;
    }

};

Mesh.cpp:

Mesh::Mesh(Vertex *vertices, unsigned int numVertices, unsigned int *indices, unsigned int numIndices) {
    // m_numIndices, VAO, VBO, VEO are members
    m_numIndices = numIndices;

    //VAO
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    //VBO
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(Vertex), vertices, GL_STATIC_DRAW);


    //EBO
    glGenBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices * sizeof(unsigned int), indices, GL_STATIC_DRAW);

    //VBO Attribute
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), nullptr);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

}

Mesh::~Mesh() {
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteBuffers(1, &EBO);
}

void Mesh::draw() {

    glBindVertexArray(VAO);
    glDrawElements(GL_TRIANGLES, m_numIndices, GL_UNSIGNED_INT, nullptr);
}

main.cpp:

#define DISPLAY_WIDTH 840
#define DISPLAY_HEIGHT 640

int main() {
    Display display(DISPLAY_WIDTH, DISPLAY_HEIGHT, "Test");
    Vertex vertex[] = {Vertex(glm::vec3(0.5f, 0.5f, 0.0f)),  // top right
                       Vertex(glm::vec3(0.5f, -0.5f, 0.0f)),  // bottom right
                       Vertex(glm::vec3(-0.5f, -0.5f, 0.0f)),  // bottom left
                       Vertex(glm::vec3(-0.5f, 0.5f, 0.0f))   // top left
    };
    unsigned int indices[] = {
            0, 1, 2,
            2, 3, 0
    };
    Mesh mesh(vertex, 4, indices, 6);
    Shader shader("./res/shaders/basicVs.shader", "./res/shaders/basicFs.shader");

    while (!display.ShouldClose()) {

        display.ProcessInput();
        display.Clear(0.2f, 0.3f, 0.3f, 1.0f);
        shader.use();
        mesh.draw();

        display.SwapBuffers();
        glfwPollEvents();
    }

    return 0;
}

Running the code will result only a working window. No drawing or something. Sorry for the long post, thanks for the help!

I'm following the first tutorials and trying to abstract OpenGL stuff into classes.

I know that you don't want to hear this, but:

Don't!

Don't try to wrap OpenGL into a class framework. Only misery, despair and anguish await you down this path.

The way OpenGL works, how it organises its internal state and reflects its internal object does not very well map into classes. On the surface it may not look like this. You may think: "Textures, yes, I'm going to wrap them into a class!"

But it doesn't work as simple as that: To stay with that example:

Textures are part of a OpenGL context. And there might be multiple OpenGL context within a process. And the namespaces of these contexts, which also may be some, but not all of them, can be shared, so that a single texture may belong to several contexts. Textures have sampling state, which you might want to switch around depending on what you're going to do. But that's sometimes unweildy and hence Sampler Objects have been introduced, which can bind to a texture, but can not be shared across contexts.

This is just a very small portion of what OpenGL offers, and already this opened a HUGE can of worms to properly map and track this in a classes based OOP design.

The amount of work you have to put into this, to make t work reasonably well is mind boggling and simply not worth it. Just use OpenGL directly.

If you absolutely feel the need to put wrappers around something, then wrap Vulkan. That APIs is meant to be used that way.

The issue is caused by Face Culling . Your setup culls back faces.

 glEnable(GL_CULL_FACE); glCullFace(GL_BACK);

If a face is front-facing or back-facing is determined by the winding order of the triangle primitive.

Your faces are clockwise (0-1-2, 2-3-0):

3        0
 +-----+ +
 |   / / |
 | / /   |
 + +-----+
2         1

Bu default front-facing polygons are counter-clockwise GL_CCW . See glFrontFace .

Change the front-facing mode ( glFrontFace(GL_CW); ) or disable face culling to solve the issue.

Alternatively you can change the winding order of the faces (eg 2-1-0, 2-0-3).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM