#include #include "GL/gl.h" #include "GL/glext.h" #include "SDL2/SDL.h" // this section is for loading OpenGL things from later versions. typedef void (APIENTRY *GLGenVertexArrays) (GLsizei n, GLuint *arrays); typedef void (APIENTRY *GLGenBuffers) (GLsizei n, GLuint *buffers); typedef void (APIENTRY *GLBindVertexArray) (GLuint array); typedef void (APIENTRY *GLBindBuffer) (GLenum target, GLuint buffer); typedef void (APIENTRY *GLBufferData) (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage); typedef void (APIENTRY *GLBufferSubData) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data); typedef void (APIENTRY *GLGetBufferSubData) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data); typedef void (APIENTRY *GLFlush) (void); typedef void (APIENTRY *GLFinish) (void); GLGenVertexArrays glGenVertexArrays = NULL; GLGenBuffers glGenBuffers = NULL; GLBindVertexArray glBindVertexArray = NULL; GLBindBuffer glBindBuffer = NULL; GLBufferData glBufferData = NULL; GLBufferSubData glBufferSubData = NULL; GLGetBufferSubData glGetBufferSubData = NULL; void load_gl_pointers() { glGenVertexArrays = (GLGenVertexArrays)SDL_GL_GetProcAddress("glGenVertexArrays"); glGenBuffers = (GLGenBuffers)SDL_GL_GetProcAddress("glGenBuffers"); glBindVertexArray = (GLBindVertexArray)SDL_GL_GetProcAddress("glBindVertexArray"); glBindBuffer = (GLBindBuffer)SDL_GL_GetProcAddress("glBindBuffer"); glBufferData = (GLBufferData)SDL_GL_GetProcAddress("glBufferData"); glBufferSubData = (GLBufferSubData)SDL_GL_GetProcAddress("glBufferSubData"); glGetBufferSubData = (GLGetBufferSubData)SDL_GL_GetProcAddress("glGetBufferSubData"); } // end OpenGL loading stuff #define CAPACITY (1 << 8) // return nonzero if an OpenGL error has occurred. int opengl_checkerr(const char* const label) { GLenum err; switch(err = glGetError()) { case GL_INVALID_ENUM: printf("GL_INVALID_ENUM"); break; case GL_INVALID_VALUE: printf("GL_INVALID_VALUE"); break; case GL_INVALID_OPERATION: printf("GL_INVALID_OPERATION"); break; case GL_INVALID_FRAMEBUFFER_OPERATION: printf("GL_INVALID_FRAMEBUFFER_OPERATION"); break; case GL_OUT_OF_MEMORY: printf("GL_OUT_OF_MEMORY"); break; case GL_STACK_UNDERFLOW: printf("GL_STACK_UNDERFLOW"); break; case GL_STACK_OVERFLOW: printf("GL_STACK_OVERFLOW"); break; default: return 0; } printf(" %s\n", label); return 1; } int main(int nargs, const char* args[]) { printf("initializing..\n"); SDL_Init(SDL_INIT_EVERYTHING); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_Window* const w = SDL_CreateWindow( "broken", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1, 1, SDL_WINDOW_OPENGL ); if(w == NULL) { printf("window was null\n"); return 0; } SDL_GLContext context = SDL_GL_CreateContext(w); if(context == NULL) { printf("context was null\n"); return 0; } load_gl_pointers(); if(opengl_checkerr("init")) { return 1; } printf("GL_VENDOR: %s\n", glGetString(GL_VENDOR)); printf("GL_RENDERER: %s\n", glGetString(GL_RENDERER)); float* const vs = malloc(CAPACITY * sizeof(float)); memset(vs, 0, CAPACITY * sizeof(float)); unsigned int i = 0; while(i < 128000) { GLuint vertex_array, vertex_buffer; glGenVertexArrays(1, &vertex_array); glGenBuffers(1, &vertex_buffer); glBindVertexArray(vertex_array); glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); if(opengl_checkerr("gen/binding")) { return 1; } glBufferData( GL_ARRAY_BUFFER, CAPACITY * sizeof(float), vs, // initialize with `vs` just to make sure it's allocated. GL_DYNAMIC_DRAW ); // verify that the memory is allocated by reading it back into `vs`. glGetBufferSubData( GL_ARRAY_BUFFER, 0, CAPACITY * sizeof(float), vs ); if(opengl_checkerr("creating buffer")) { return 1; } glFlush(); glFinish(); // segfault occurs here.. glBufferSubData( GL_ARRAY_BUFFER, 0, CAPACITY * sizeof(float), vs ); glFlush(); glFinish(); ++i; } return 0; }