C++ 为什么顶点数组对象会导致错误?

C++ 为什么顶点数组对象会导致错误?,c++,opengl,sdl,vao,C++,Opengl,Sdl,Vao,我有一个opengl程序,可以工作。。。直到我尝试使用顶点数组对象。我已经尝试了几天来来回更改代码,但找不到问题所在 这是代码的一部分。glCall(…)是用于错误检查的辅助函数 static struct { GLint color; GLuint vertices; GLuint mvpMatrix; const char * vertexCode = R"___( #version 330 core

我有一个opengl程序,可以工作。。。直到我尝试使用顶点数组对象。我已经尝试了几天来来回更改代码,但找不到问题所在

这是代码的一部分。glCall(…)是用于错误检查的辅助函数

    static struct {
    GLint color;
    GLuint vertices;
    GLuint mvpMatrix;

    const char * vertexCode =
        R"___(
        #version 330 core

        in vec4 vPosition;

        uniform vec4 uColor;
        uniform  mat4    mvp_matrix;
        out vec4 fColor;
        void main() {
           gl_Position = mvp_matrix * vPosition;
           fColor = uColor;
        }
    )___";


    const char * fragmentCode =
        R"__(
        #version 330 core
        in vec4 fColor;
        out vec4 FragColor;

        void main() {
          gl_FragColor = fColor;
        })__";

} program1;



static Matrix<float> mvpMatrix;
static double screenWidth, screenHeight;
static ShaderProgram squareShaderProgram;

static GLuint vertexArray;
static GLuint vertexBuffer;


//Square
static const vector<float> squareVertices = { 0.f, 0.f, 1.f, 0.f, 1.f, 1.f, 0.f, 1.f };
static const vector<float> squareColors = {.8, .8, 1., 1};



static void setDimensions(double width, double height){
    screenWidth = width;
    screenHeight = height;
}


static bool initDrawModule(double width, double height) {
    //GLuint vao;  <-----------------------  //This seems to be the problem
    //glCall(glGenVertexArrays(1, &vao));
    //glCall(glBindVertexArray(vao));



    squareShaderProgram.initProgram(program1.vertexCode, program1.fragmentCode);


    if (!squareShaderProgram.getProgram()) {
        cerr << "Could not create shader program in " << __FILE__ << ":" << __LINE__ << endl;
        return false;
    }


    glCall(squareShaderProgram.use());

    program1.vertices = squareShaderProgram.getAttribute("vPosition");
    program1.color = squareShaderProgram.getUniform("uColor");
    program1.mvpMatrix = squareShaderProgram.getUniform("mvp_matrix");



    setDimensions(width, height);

    return false;
}


static void drawSquare(Vec p, double a, double sx, double sy){
    squareShaderProgram.use();

    {
        mvpMatrix = mvpMatrix.RotationZ(a / 180.);
        mvpMatrix.scale(sx, sy, 1);

        mvpMatrix.scale(1. / screenWidth, 1. / screenHeight, 1);
        mvpMatrix.setTranslation(
            p.x / screenWidth * 2 - 1.,
            p.y / screenHeight * 2 - 1.,
            p.z
        );

        glCall(glUniformMatrix4fv(program1.mvpMatrix, 1, GL_FALSE, mvpMatrix));
    }


    glCall(glEnableVertexAttribArray(program1.vertices));
    glCall(glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer))
    glCall(glVertexAttribPointer( //<----- this fails
            program1.vertices,
            2,
            GL_FLOAT,
            GL_FALSE,
            0,
            &squareVertices[0]));

    glCall(glUniform4fv(program1.color, 1, &squareColors[0]));
    glCall(glDrawArrays(GL_TRIANGLE_FAN, 0, 4));
    glDisableVertexAttribArray(program1.vertices);
}



static void render() {
    static float x = 0;

    drawSquare(Vec(.1 + x, 50, 1), 20 + x * 2, 100,100);
    x += 20;
}




bool init() {
    return initDrawModule(512, 512);
}





void die(string message);
void checkSDLError(int line = -1);



int main(int argc, char *argv[])
{
    SDL_Window *mainwindow; 
    SDL_GLContext maincontext; 

    // Create our window centered at 512x512 resolution
    mainwindow = SDL_CreateWindow("sdl-window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
        512, 512, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
    if (!mainwindow) {
        die("Unable to create window");
    }

    checkSDLError(__LINE__);


    maincontext = SDL_GL_CreateContext(mainwindow);
    checkSDLError(__LINE__);

    init();

    SDL_GL_SetSwapInterval(1);

    for (int i = 0; i < 10; ++i) {
        glClearColor ( 0.1 * i, 0.0, 0.0, 1.0 );
        glClear ( GL_COLOR_BUFFER_BIT );
        render();
        SDL_GL_SwapWindow(mainwindow);
        SDL_Delay(200);
    }

    SDL_GL_DeleteContext(maincontext);
    SDL_DestroyWindow(mainwindow);
    SDL_Quit();

    return 0;
}
静态结构{
闪烁的颜色;
胶合顶点;
GLuint MVP矩阵;
常量字符*顶点代码=
R“___(
#330版核心
在vec4位置;
均匀的维柯色;
均匀mat4-mvp_矩阵;
输出vec4颜色;
void main(){
gl_位置=mvp_矩阵*V位置;
fColor=uColor;
}
)___";
常量字符*碎片代码=
R“__(
#330版核心
在vec4彩色;
out vec4 FragColor;
void main(){
gl_FragColor=fColor;
})__";
}方案1;
静态矩阵MVP矩阵;
静态双屏幕宽度、屏幕高度;
静态着色器程序SquareShader程序;
静态胶合顶点阵列;
静态GLuint顶点缓冲区;
//方格
静态常数向量平方顶点={0.f,0.f,1.f,0.f,1.f,1.f,0.f,1.f};
静态常量向量平方颜色={.8,8,1,1};
静态空隙设置尺寸(双倍宽度、双倍高度){
屏幕宽度=宽度;
屏幕高度=高度;
}
静态布尔模块(双宽双高){

//GLuint vao;GL\u INVALID\u操作
是由指向数据的指针的最后一个参数引起的

在兼容性配置文件中,如果顶点缓冲区对象0已绑定,则
glvertexattributepointer
的最后一个参数将被视为指向顶点数组数据的指针

如果已绑定命名顶点缓冲区对象,则
glvertexattributepointer
的最后一个参数是该缓冲区内的偏移量

您混合了这两种情况,绑定了命名缓冲区对象,但也传递了指向顶点数组数据的指针:

glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(program1.vertices, 2, GL_FLOAT, GL_FALSE, 0, &squareVertices[0]);
如果要使用顶点缓冲区对象,则必须使用创建和初始化缓冲区对象的数据存储:

glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
GLsizeiptr size_in_bytes = ...; // size of the buffer data in bytes
glBufferData(GL_ARRAY_BUFFER, size_in_bytes, &squareVertices[0], GL_STATIC_DRAW);
命名顶点缓冲区可用于定义通用顶点属性数据数组:

glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(program1.vertices, 2, GL_FLOAT, GL_FALSE, 0, NULL);

另请参见。

Aha这就是为什么我从未让glVertexAttribBuffer与glVertexAttibPointer一起工作。我有红色的它,但直到现在我才完全得到它。现在我开始工作了,我意识到如果不使用VertexBuffers(正确)并且在修复程序时按照预期工作,VertexArray似乎无法工作。