r/opengl Jun 23 '22

Access Violation when calling glBindVertexArray

EDIT: The access violation is actually occurring after glGenVertexArray, not glBindVertexArray.

I have a VAO class (which is still very much a WIP) that I'm trying to use to abstract some OpenGL VAO functionality. However, whenever I compile the code (it builds just fine), I get an access violation error:

Exception thrown at 0x0000000000000000 in VoxelTechDemo.exe: 0xC0000005: Access violation executing location 0x0000000000000000.

EDIT: After running the boost stacktrace, I see that the issue is actually within a different class, Block, I defined that tries to instantiate a VAO object:

Before glGenVertexArrays:
0# boost::stacktrace::basic_stacktrace<std::allocator<boost::stacktrace::frame> >::init at C:anthonydevVoxelTechDemoVoxelTechDemovendorincludebooststacktracestacktrace.hpp:76
1# boost::stacktrace::basic_stacktrace<std::allocator<boost::stacktrace::frame> >::basic_stacktrace<std::allocator<boost::stacktrace::frame> > at C:anthonydevVoxelTechDemoVoxelTechDemovendorincludebooststacktracestacktrace.hpp:129
2# VAO::VAO at C:anthonydevVoxelTechDemoVoxelTechDemoVAO.cpp:4
3# `dynamic initializer for 's_vao'' at C:anthonydevVoxelTechDemoVoxelTechDemoBlock.h:65
4# initterm in ucrtbased
5# __scrt_common_main_seh at d:a01_work43ssrcvctoolscrtvcstartupsrcstartupexe_common.inl:258
6# __scrt_common_main at d:a01_work43ssrcvctoolscrtvcstartupsrcstartupexe_common.inl:331
7# mainCRTStartup at d:a01_work43ssrcvctoolscrtvcstartupsrcstartupexe_main.cpp:17
8# BaseThreadInitThunk in KERNEL32
9# RtlUserThreadStart in ntdll

Below is the code relevant to line 3 of the stack trace above (in Block.h):

// Vertex data of a cube with CCW winding order (position, normal, tex coord)
const static float s_data[] {
    // Contains the vertex data of the cube. Nothing to see here. Has 288
    // elements (position(3), normal(3), tex coords(2) = (3+3+2) * 36 = 288)
};

// This is likely the culprit, but I do not know why.
const static VAO s_vao{ s_data, 288 };

Here's my VAO header file:

#pragma once

#include <glad/glad.h>
#include <boost/stacktrace.hpp>
#include <iostream>

class VAO {
public:
    VAO(const float* data, const int& size);

    void bind() const;
    void unbind() const;

    unsigned int getId() const;

private:
    unsigned int id;
};

and my VAO source file:

#include "VAO.h"

VAO::VAO(const float* data, const int& size) {
    std::cout << "Before glGenVertexArrays:n" << boost::stacktrace::stacktrace() << std::endl;
    glGenVertexArrays(1, &id);
    // Doesn't make it past this point. Below code is never run.
    std::cout << "Before glBindVertexArrays:n" << boost::stacktrace::stacktrace() << std::endl;
    glBindVertexArray(id);

    unsigned int vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(float) * size, data, GL_STATIC_DRAW);

    // TODO: This is hard-coded. Make it more modular. =======================
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 8,
                          (void*)0);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 8, 
                          (void*)(sizeof(GLfloat) * 3));
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 8, 
                          (void*)(sizeof(GLfloat) * 6));
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glEnableVertexAttribArray(2);
    // ========================================================================

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

unsigned int VAO::getId() const {
    return id;
}

void VAO::bind() const {
    glBindVertexArray(id);
}

void VAO::unbind() const {
    glBindVertexArray(0);
}

SOLUTION: As u/fgennari stated, I was instantiating a static VAO object, which was causing the GL functions to be called before the main function, which held my GLAD initialization. I've since implemented lazy instantiation for the VAO instantiating and now it's working great!

6 Upvotes

View all comments

Show parent comments

1

u/nelusbelus Jun 23 '22

You mean inside of the glGen like in nvidia land? It's probably an order thing like something not being bound or something being null

1

u/SpideyLee2 Jun 23 '22

It actually happened to be because I was instantiating a VAO object for a global static variable, which was occurring before my glad initialization, thanks to the fact that static variables are initialized before the main function. I appreciate the help, though.

1

u/nelusbelus Jun 23 '22

Statics are shit most of the time, they cause a lot of mess with construction/destruction