繁体   English   中英

创建网格 class 并实现不会生成 model OpenGL?

[英]Creating Mesh class and implementing does not generate model OpenGL?

I'm trying to create a Mesh class that can generate a model for me and then calling that model in the createTriangle function. 但是,每当我尝试创建meshObj1meshObj2然后将其推送到meshVector时,它不想渲染吗? 为什么会这样?

网格.h

#ifndef MESH_H
#define MESH_H

#include "GL/glew.h"

class Mesh {
    public:
        Mesh();
        ~Mesh();

        void createMesh(GLfloat *vertices, unsigned int *indices, unsigned int numOfVertices, unsigned int numOfIndices);
        void renderMesh();
        void clearMesh();


    private:
        GLuint VAO, VBO, IBO;
        GLsizei indexCount;
};

#endif

网格.cpp

#include "Mesh.h"

Mesh::Mesh() {
    VAO = 0;
    VBO = 0;
    IBO = 0;
    indexCount = 0;
}

Mesh::~Mesh() {
    clearMesh();
}

void Mesh::createMesh(GLfloat* vertices, unsigned int* indices, unsigned int numOfVertices, unsigned int numOfIndices) {
    indexCount = numOfIndices;

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

    //Information
    //VBO Information
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0] * numOfVertices), vertices, GL_STATIC_DRAW);

    //IBO Information
    glGenBuffers(1, &IBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0]) * numOfIndices, indices, GL_STATIC_DRAW);


    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);

    //Unbinding
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

}

void Mesh::renderMesh() {
    //Binding
    glBindVertexArray(VAO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);

    //Rendering
    glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, 0);

    //Unbinding
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}

void Mesh::clearMesh() {
    if (VAO != 0) {
        glDeleteVertexArrays(1, &VAO);
        VAO = 0;
    }

    if (VBO != 0) {
        glDeleteBuffers(1, &VBO);
        VBO = 0;
    }

    if (IBO != 0) {
        glDeleteBuffers(1, &IBO);
        IBO = 0;
    }

    indexCount = 0; 
}

主文件

#include "GL/glew.h"
#include "GLFW/glfw3.h"

#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"

#include <iostream>
#include <vector>
#include <memory>

#include "Mesh.h"


//Window dimensions
const GLint SCREEN_WIDTH = 1280, SCREEN_HEIGHT = 900;
GLuint shader, uniformModel, uniformProjection;

bool isMovingLeft = true; 
float triOffset = 0.f;
float triMaxOffset = 0.7;
float triIncrement = 0.005;


std::vector<Mesh*> meshVector;


//Vertex shader
static const char* vShader = "                                      \n\
    #version 460                                                    \n\
                                                                    \n\
    layout(location = 0) in vec3 pos;                               \n\
                                                                    \n\
    out vec4 vColor;                                                \n\
                                                                    \n\
    uniform mat4 model;                                             \n\
    uniform mat4 projection;                                        \n\
                                                                    \n\
    void main() {                                                   \n\
        gl_Position = projection * model * vec4(pos, 1.0);          \n\
        vColor = vec4(clamp(pos, 0.f, 1.f), 1.f);                   \n\
    };                                                              \n\
";

//Fragment shader
static const char* fShader = "                                      \n\
    #version 460                                                    \n\
                                                                    \n\
    in vec4 vColor;                                                 \n\
                                                                    \n\
    out vec4 color;                                                 \n\
                                                                    \n\
    void main() {                                                   \n\
        color = vColor;                                             \n\
    };                                                              \n\
";


void createTriangle() {
    unsigned int indices[] = {
        0, 3, 1,
        1, 3, 2,
        2, 3, 0,
        0, 1, 2
    };


    //Points of the triangle 
    GLfloat vertices[] = {
        -1.f, -1.f, 0.f, 
         0.f, -1.f, 1.f, 
         1.f, -1.f, 0.f, 
         0.f,  1.f, 0.f  
    };


    Mesh* meshObj1 = new Mesh();
    meshObj1->createMesh(vertices, indices, 12, 12);
    meshVector.push_back(meshObj1);

    Mesh* meshObj2 = new Mesh();
    meshObj2->createMesh(vertices, indices, 12, 12);
    meshVector.push_back(meshObj2);
}

void addShader(GLuint theProgram, const char* shaderCode, GLenum shaderType) {
    GLuint theShader = glCreateShader(shaderType);

    const GLchar* theCode[1];
    theCode[0] = shaderCode;

    GLint codeLength[1];
    codeLength[0] = strlen(shaderCode);

    glShaderSource(theShader, 1, theCode, codeLength);
    glCompileShader(theShader);


    //Getting error information for linking
    GLint result = 0;
    GLchar eLog[1024] = { 0 };

    glGetShaderiv(theShader, GL_COMPILE_STATUS, &result);
    if (result != GL_TRUE) {
        glGetShaderInfoLog(theShader, sizeof(eLog), NULL, eLog);
        std::cout << "Error compiling the " << shaderType << ' ' << eLog << '\n';
    }


    glAttachShader(theProgram, theShader);

}

void compileShaders() {
    shader = glCreateProgram();

    if (shader != GL_TRUE) {
        std::cout << "Shader program error!\n";
    }

    //Adding shaders
    addShader(shader, vShader, GL_VERTEX_SHADER);
    addShader(shader, fShader, GL_FRAGMENT_SHADER);

    //Getting error information for linking
    GLint result = 0;
    GLchar eLog[1024] = { 0 };

    //Linking shader
    glLinkProgram(shader);

    //Shader linking status
    glGetProgramiv(shader, GL_LINK_STATUS, &result);
    if (result != GL_TRUE) {
        glGetProgramInfoLog(shader, sizeof(eLog), NULL, eLog);
        std::cout << "Error linking program! " << eLog << '\n';
    }


    //Gets shader ID and then binds it with the variable inside shader
    uniformModel = glGetUniformLocation(shader, "model");
    uniformProjection = glGetUniformLocation(shader, "projection");
}


int main() {
    //Initialize GLFW
    if (glfwInit() != GLFW_TRUE) {
        std::cout << "GLFW init failed\n";
        glfwTerminate();
    }


    //Setup GLFW window properties
    //OpenGL version
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); //Large version
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4); //Small version 
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //Detects any old OpenGL code, this will throw an error
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); //Allows forward compatibility (between differnt OS) 


    //Creating window
    GLFWwindow* window;
    window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "OpenGL Test Window", NULL, NULL);
    glfwSetWindowPos(window, 250, 100);

    if (window == NULL) {
        std::cout << "GLFW window creation failed!\n";
        glfwTerminate();
    }

    //Get buffer size information
    int bufferWidth, bufferHeight;
    glfwGetFramebufferSize(window, &bufferWidth, &bufferHeight);

    //Set context for GLEW to use (can change between which window)
    glfwMakeContextCurrent(window);

    //Allow modern extension features
    glewExperimental = GL_TRUE;


    if (glewInit() != GLEW_OK) {
        std::cout << "Glew init failed!\n";
        glfwDestroyWindow(window);
        glfwTerminate();
    }



    glEnable(GL_DEPTH_TEST);

    //Setup viewport size
    glViewport(0, 0, bufferWidth, bufferHeight);


    createTriangle();
    compileShaders();


    glm::mat4 projection = glm::perspective(45.f, (GLfloat)bufferWidth / (GLfloat)bufferHeight, 0.1f, 100.f);



    //Main game loop
    while (!glfwWindowShouldClose(window)) {
        //Get + Handle user input events
        glfwPollEvents();

        //Left-Right
        if (isMovingLeft) {
            triOffset += triIncrement;
        }

        else {
            triOffset -= triIncrement;
        }


        if (abs(triOffset) >= triMaxOffset) {
            isMovingLeft = !isMovingLeft;
        }


        //Clear window
        glClearColor(0.f, 0.f, 0.f, 1.f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

        glUseProgram(shader);

        //Matrix 4x4
        glm::mat4 model(1.f);
        model = glm::translate(model, glm::vec3(triOffset, 0.f, -2.5f));
        model = glm::scale(model, glm::vec3(0.4f, 0.4f, 1.f));
        glUniformMatrix4fv(uniformModel, 1, GL_FALSE, glm::value_ptr(model));
        glUniformMatrix4fv(uniformProjection, 1, GL_FALSE, glm::value_ptr(projection));
        meshVector[0]->renderMesh();

        model = glm::mat4(1.f);
        model = glm::translate(model, glm::vec3(-triOffset, 1.f, -2.5f));
        model = glm::scale(model, glm::vec3(0.4f, 0.4, 1.f));
        meshVector[1]->renderMesh();


        glUseProgram(0);

        glfwSwapBuffers(window);
    }
}

我预计两个金字塔会形成颜色。

GL_ELEMENT_ARRAY_BUFFER目标绑定存储在顶点数组 Object中。 请参阅索引缓冲区

这意味着,该指令

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

打破了之前IBO与顶点数组 object VAO的绑定。 从您的代码中删除此指令,以解决问题。

请注意, GL_ARRAY_BUFFERGL_ELEMENT_ARRAY_BUFFER的行为不同。 当前的GL_ARRAY_BUFFER绑定是全局 state,但GL_ELEMENT_ARRAY_BUFFER绑定在当前顶点数组 Object 中说明。
此外,在 VAO 的GL_ARRAY_BUFFER向量中说明了 GL_ARRAY_BUFFER,但是当调用glVertexAttribPointer时会发生这种情况。 当调用glVertexAttribPointer时,当前绑定到目标GL_ARRAY_BUFFER的缓冲区与指定索引的顶点属性相关联。

这会导致GL_ELEMENT_ARRAY_BUFFERGL_ARRAY_BUFFER的行为不同。 一个 VAO 只能引用 1 个索引(元素)缓冲区,但它可以引用多个数组缓冲区。 每个属性(索引)都可以关联到不同的缓冲区。


在渲染第二个网格之前,您已将相应的 model 矩阵设置为已安装程序的默认统一块:

glUseProgram(shader);
glUniformMatrix4fv(uniformProjection, 1, GL_FALSE, glm::value_ptr(projection));

glm::mat4 model(1.f);
model = glm::translate(model, glm::vec3(triOffset, 0.f, -2.5f));
model = glm::scale(model, glm::vec3(0.4f, 0.4f, 1.f));
glUniformMatrix4fv(uniformModel, 1, GL_FALSE, glm::value_ptr(model));        
meshVector[0]->renderMesh();

model = glm::mat4(1.f);
model = glm::translate(model, glm::vec3(-triOffset, 1.f, -2.5f));
model = glm::scale(model, glm::vec3(0.4f, 0.4, 1.f));
glUniformMatrix4fv(uniformModel, 1, GL_FALSE, glm::value_ptr(model)); // <---
meshVector[1]->renderMesh();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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