glGenVertexArrays(1,&shapes [i] .vao);不工作/段故障

时间:2018-07-17 21:42:43

标签: c++ opengl

以下特定代码行出现错误:

glGenVertexArrays(1, &shapes[i].vao);

直到那时我的程序运行正常,然后控制台停止工作并崩溃。我正在尝试具有多个vao和vbo,以便可以在屏幕上具有多个对象。这是整个代码的其余部分:

#define GLM_FORCE_RADIANS
#include <iostream>
#include <fstream>
#include <string>
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <GLFW/glfw3.h>
using namespace std;
struct vertex{
    float x = 0;
    float y = 0;
    float z = 0;
    float r = 0;
    float g = 0;
    float b = 0;
    float a = 0;
};
struct shape{
    public:
    int numOfVertecies;
    GLenum typeOfShape;
    vertex* vertices;
    GLuint vao;
    GLuint vbo;
    /*shape(){
        numOfVertecies = 0;
        vertices = {};
        typeOfShape = GL_TRIANGLES;
    }
    mkshape(vertex* v,int n,GLenum t){
        numOfVertecies = n;
        vertices = v;
        typeOfShape = t;
    }
    ~shape(){
        glDeleteBuffers(1, &vbo);
        glDeleteVertexArrays(1, &vao);
    }
    setDrawType(GLenum t){
        typeOfShape = t;
    }*/
};
string LoadVertexCode();
string LoadFragmentCode();
shape mkShape(vertex*,int,GLenum);
vertex mkVert(float,float,float,float,float,float,float);
static void key_callback(GLFWwindow*, int, int, int, int);
GLuint u_transform;
glm::mat4 tmat(1.0f);
GLuint colorChange;
bool ESCLoop = true;
float rotation = 0;
float xChange;
float yChange;

int main()
{
    int numOfShapes;
    cout << "Welcome to the shape maker. How many shapes would you like to make: ";
    cin >> numOfShapes;
    int sides;
    float xCenter;
    float yCenter;
    float radius;
    shape *shapes = new shape[numOfShapes];
    shape *temp;
    for(int i = 0; i< numOfShapes; i++)
    {
        cout << "How many sides would you like for shape " << i+1 <<": ";
        cin >> sides;
        cout << "Radius(center to vertex): ";
        cin >> radius;
        cout << "Center coordinate for X: ";
        cin >> xCenter;
        cout << "Center coordinate for Y: ";
        cin >> yCenter;
        vertex buffer[sides];
        for(int j = 0;j<sides;j++)
        {
            buffer[j] = mkVert(cos((j/sides)*2*M_PI)*radius+xCenter,sin((j/sides)*2*M_PI)*radius+yCenter,0.0,1.0,1.0,0.0,1.0);
        }
        shapes[i] = mkShape(buffer,sides,GL_LINE_LOOP);
        glGenVertexArrays(1, &shapes[i].vao);
        glBindVertexArray(shapes[i].vao);

        glGenBuffers(1, &shapes[i].vbo);                                  //create the Vertex Buffer Object
        glBindBuffer(GL_ARRAY_BUFFER, shapes[i].vbo);                     //bind the empty VBO
        glBufferData(GL_ARRAY_BUFFER, shapes[i].numOfVertecies*7*sizeof(vertex), shapes[i].vertices, GL_STATIC_DRAW);  //store vertex data on the graphics card in the VBO

        glEnableVertexAttribArray(0);
            //enable attribute 0
        glVertexAttribPointer(  0, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), (void*)0 ); //configure attribute 0

        glEnableVertexAttribArray(1);
        glVertexAttribPointer(  1, 4, GL_FLOAT, GL_FALSE, sizeof(vertex), (void*)(3 * sizeof(float)) );  //configure attribute 0

        glBindVertexArray(0);
    }
    /*vertex v1[] = {
        mkVert(-0.5f, -0.43f, 0.0f, 0.8f, 0.09f, 0.45f, 1.0f),
        mkVert( 0.0f,  0.43f, 0.0f, 0.2f, 0.75f, 0.0f, 1.0f),
        mkVert( 0.5f, -0.43f, 0.0f, 1.0f, 0.314159265f, 0.16f, 1.0f)
    };
    vertex v2[] = {    //array of vertex positions
        mkVert(-0.5f, -0.1f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f),
        mkVert( -0.6f,  1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f),
        mkVert( 0.85f, 0.43f, 0.0f,0.0f, 0.0f, 1.0f, 0.50f) //position
    };
    vertex v3[] = {
        mkVert(0.0f,0.0f,0.0f,0.5f,0.5f,0.5f,1.0f),
        mkVert(-1.0f,-0.5f,0.0f,0.1f,0.2f,0.5f,1.0f),
        mkVert(1.0f,0.9f,0.0f,1.0f,0.0f,0.3f,1.0f)
    };
    shape shapes[] = {
        mkShape(v1,3,GL_TRIANGLES),
        mkShape(v2,3,GL_TRIANGLES),
        mkShape(v3,3,GL_TRIANGLES)
    };*/
    int amountOFrames = 0;
    glfwInit(); //Initalize GLFW
    GLFWwindow* mWindow = glfwCreateWindow(800,800, "Big Gay!", NULL, NULL); //Create the window.
    if(!mWindow){ //If the window isn't working, Error.
        glfwTerminate();
        cerr << "Window creation failed!" << endl;
        return -1;
    }
    glfwMakeContextCurrent(mWindow); // Make the GLFW context to actually run the damn code.
    if(!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)){ //If GLad(05) no work, Error.
     glfwTerminate();
     cerr << "GLAD failed to initialize!" << endl;
        return -1;
    }
    ///SET UP SHADERS
    string vertexCode = LoadVertexCode();
    string fragmentCode = LoadFragmentCode();

    const GLchar* vertexCodeCSTR[1];  //convert C++ strings into arrays of C strings
    const GLchar* fragmentCodeCSTR[1];
    vertexCodeCSTR[0] = (GLchar*)(vertexCode.c_str());
    fragmentCodeCSTR[0] = (GLchar*)(fragmentCode.c_str());

    GLint vertexCodeLength[1];  //create arrays of string lengths
    GLint fragmentCodeLength[1];
    vertexCodeLength[0] = vertexCode.length();
    fragmentCodeLength[0] = fragmentCode.length();

    GLint vertexSuccess = 0;  //set up variable to store compilation status
    GLint fragmentSuccess = 0;
    GLint programSuccess = 0;

    GLuint mVertexShader = glCreateShader(GL_VERTEX_SHADER);
    GLuint mFragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

    glShaderSource(mVertexShader, 1, vertexCodeCSTR, vertexCodeLength);
    glShaderSource(mFragmentShader, 1, fragmentCodeCSTR, fragmentCodeLength);

    glCompileShader(mVertexShader);
    glCompileShader(mFragmentShader);

    glGetShaderiv(mVertexShader, GL_COMPILE_STATUS, &vertexSuccess);
    glGetShaderiv(mFragmentShader, GL_COMPILE_STATUS, &fragmentSuccess);

    if(vertexSuccess == GL_FALSE || fragmentSuccess == GL_FALSE)
    {
        cerr << "One or more shaders failed to compile!" << endl;
        glfwTerminate();
        return -1;
    }

    GLuint mProgram = glCreateProgram(); //create a "program", which links the vertex and fragment shaders

    glAttachShader(mProgram, mVertexShader);   //attach both shaders to the program
    glAttachShader(mProgram, mFragmentShader);

    glBindAttribLocation(mProgram, 0, "a_position"); //bind the position attribute location
    glBindAttribLocation(mProgram, 1, "a_color");

    glLinkProgram(mProgram);    //link the program
    glGetProgramiv(mProgram, GL_LINK_STATUS, &programSuccess);  //check for linking success

    if(programSuccess == GL_FALSE)    //continue if the program linked successfully
    {
       cerr << "Program failed to link!" << endl;
    glfwTerminate();
       return -1;
    }

    glValidateProgram(mProgram); //validate the program
    glGetProgramiv(mProgram, GL_VALIDATE_STATUS, &programSuccess);

    if(programSuccess == GL_FALSE)    //continue if the program linked successfully
    {
        cerr << "Program failed to validate!" << endl;
        glfwTerminate();
        return -1;
    }
    GLuint u_transform = glGetUniformLocation(mProgram, "u_transform");
    colorChange = glGetUniformLocation(mProgram, "colorChange");

    glUniform1f(colorChange, 0.0f);
    glUseProgram(mProgram);
    float colorChangef = 0.0;
    float change = 0.0001;
    xChange = 0;
    yChange = 0;
     tmat = glm::translate(glm::mat4(1.0f), glm::vec3(0.001, 0.0, 0.0)) * tmat;
    float xPos = 0;
    float yPos = 0;
    while(!glfwWindowShouldClose(mWindow)&&ESCLoop) //animation loop
    {
        glClear(GL_COLOR_BUFFER_BIT);
        glfwPollEvents();
        xPos += xChange;
        yPos += yChange;
        tmat = glm::translate(glm::mat4(1.0f),glm::vec3(-xPos,-yPos,0.0)) * tmat;
        tmat = glm::rotate(glm::mat4(1.0f), glm::radians(rotation+0.014f), glm::vec3(0.0, 0.0, 1.0)) * tmat;
        tmat = glm::translate(glm::mat4(1.0f), glm::vec3(xChange+xPos, yChange+yPos, 0.0)) * tmat;
        glUniformMatrix4fv(u_transform, 1, GL_FALSE, glm::value_ptr(tmat));
        for(int i = 0;i < numOfShapes;i++)
        {
            glBindVertexArray(shapes[i].vao);
            glDrawArrays(shapes[i].typeOfShape, 0, shapes[i].numOfVertecies); //Drawing
        }

        colorChangef += change;
        if(colorChangef > 1)
            change = -0.0006;
        if(colorChangef < -1)
            change = 0.0003;

        glUniform1f(colorChange, colorChangef);
        glfwSwapBuffers(mWindow);
        glfwSetKeyCallback(mWindow, key_callback);
        amountOFrames++;
    }
    glfwTerminate();
    cout << "Frames: " << amountOFrames << endl;
    return 0;
}
string LoadVertexCode(){
    string vertexCode = "";
    string line;
    ifstream myfile;

    myfile.open("vertexCode.txt", ios::in);
    if (myfile.is_open())
    {
        while (getline(myfile,line))
        {
            cout << line + "\n";
            vertexCode += line + "\n";
        }
        myfile.close();
    }
    else
    {
        myfile.close();
        cout << "Unable to open first file";
        return "";
    }
    return vertexCode;
}
string LoadFragmentCode(){
    string line;
    ifstream myfile;
    string fragmentCode = "";
    myfile.open("fragmentCode.txt", ios::in);
    if (myfile.is_open())
    {
        while (getline(myfile,line))
        {
            cout << line + "\n";
            fragmentCode += line + "\n";
        }
        myfile.close();
    }
    else
    {
        cout << "Unable to open second file";
        return "";
    }
    return fragmentCode;
}
vertex mkVert(float x, float y, float z, float r, float g ,float b, float a){
    vertex ret;
    ret.x = x;
    ret.y = y;
    ret.z = z;
    ret.r = r;
    ret.g = g;
    ret.b = b;
    ret.a = a;
    return ret;
}
shape mkShape(vertex* v,int n,GLenum t){
        shape ret;
        ret.numOfVertecies = n;
        ret.typeOfShape = t;
        ret.vertices = v;
        return ret;
    }
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods){
    if (key == GLFW_KEY_SPACE){
        if(action == GLFW_PRESS)
        {
            cout << "Space Key pressed." << endl;
            tmat = glm::translate(glm::mat4(1.0f), glm::vec3(0.0,0.1, 0.0)) * tmat;
        }
        if(action == GLFW_RELEASE)
        {
           cout << "Space Key released." << endl;
           tmat = glm::translate(glm::mat4(1.0f), glm::vec3(0.0,-0.1, 0.0)) * tmat;
        }
    }
    if(key == GLFW_KEY_ESCAPE)
        if(action == GLFW_PRESS)
        {
            cout << "Escape" << endl;
            ESCLoop = false;
        }
    if(key == GLFW_KEY_ENTER)
    {
        if(action == GLFW_PRESS)
        {
            cout << "Enter Pressed" << endl;
        }
        if(action == GLFW_RELEASE)
        {
            cout << "Enter Released" << endl;
        }
    }
    if(key == GLFW_KEY_R)
    {
        if(action == GLFW_PRESS)
        {
            cout << "Rotate" << endl;
            rotation  = 0.04;
        }
        if(action == GLFW_RELEASE)
        {
            cout << "Stop Rotate" << endl;
            rotation  = 0;
        }
    }
    if(key == GLFW_KEY_S)
    {
        if(action == GLFW_PRESS)
        {
            cout << "Extend" << endl;
            tmat = glm::scale(glm::mat4(1.0f), glm::vec3(1.5f, 1.5f, 1.0f)) * tmat;
        }
        if(action == GLFW_RELEASE)
        {
            cout << "Shrink" << endl;
            tmat = glm::scale(glm::mat4(1.0f), glm::vec3((2.0f/3), (2.0f/3), 1.0f)) * tmat;
        }
    }
    if(key == GLFW_KEY_LEFT)
    {
        if(action == GLFW_PRESS)
        {
            cout << "Left" << endl;
            xChange -= 0.001;
        }
        if(action == GLFW_RELEASE)
        {
            cout << "Stop Left" << endl;
            xChange += 0.001;
        }
    }
    if(key == GLFW_KEY_RIGHT)
    {
        if(action == GLFW_PRESS)
        {
            cout << "Right" << endl;
            xChange += 0.001;
        }
        if(action == GLFW_RELEASE)
        {
            cout << "Stop Right" << endl;
            xChange -= 0.001;
        }
    }
    if(key == GLFW_KEY_UP)
    {
        if(action == GLFW_PRESS)
        {
            cout << "Up" << endl;
            yChange += 0.001;
        }
        if(action == GLFW_RELEASE)
        {
            cout << "Stop Up" << endl;
            yChange -= 0.001;
        }
    }
    if(key == GLFW_KEY_DOWN)
    {
        if(action == GLFW_PRESS)
        {
            cout << "Down" << endl;
            yChange -= 0.001;
        }
        if(action == GLFW_RELEASE)
        {
            cout << "Stop Down" << endl;
            yChange += 0.001;
        }
    }
}

0 个答案:

没有答案