title: OpenGL model renders fine for a while, then it renders sparsely after a random amount of time
body: <p>I hacked together a sample OpenGL demo, and I have noticed an issue. I can load and render a model correctly. After a few seconds, however, the model stops being rendered correctly. </p>
  
  <p><strong>EDIT: The change from normal to bad happens at after a random amount of seconds and occurs instantly. Once it goes bad, it never changes back.</strong></p>
  
  <p><strong>All the EventLoop::Start() function does right now is block and call the callback in a loop until isRunning is false.</strong></p>
  
  <p>Here is what the model looks like before it messes up:
  <a href="https://i.stack.imgur.com/IQmnp.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/IQmnp.png" alt="fine model"></a></p>
  
  <p>Here is what it looks like after a few seconds:
  <a href="https://i.stack.imgur.com/9SlTh.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/9SlTh.png" alt="broken model"></a></p>
  
  <p>Here is my code:</p>
  
  <pre><code>// nasty globals
  static Camera* camera;
  static ModelData dragonModel;
  static ShaderProgram program;
  
  using namespace std;
  
  // called by an event loop class until isRunning is false
  void callback(bool *isRunning)
  {
          SDL_Event event;
          while(SDL_PollEvent(&amp;event))
          {
              // update the camera position
              switch(event.type)
              {
              case SDL_QUIT:
                  *isRunning = false;
                  SDL_Quit();
                  break;
              case SDL_KEYDOWN:
                  switch(event.key.keysym.sym)
                  {
                  case SDLK_UP:
                      camera-&gt;MoveBy(glm::vec3(0, 1, 0));
                      break;
                  case SDLK_DOWN:
                      camera-&gt;MoveBy(glm::vec3(0, -1, 0));
                      break;
                  case SDLK_RIGHT:
                      camera-&gt;MoveBy(glm::vec3(1, 0, 0));
                      break;
                  case SDLK_LEFT:
                      camera-&gt;MoveBy(glm::vec3(-1, 0, 0));
                      break;
                  case SDLK_w:
                      camera-&gt;MoveTo(glm::vec3(0, 0, -5));
                      break;
                  case SDLK_s:
                      camera-&gt;MoveTo(glm::vec3(0, 0, 5));
                      break;
                  default:
                      break;
                  }
              default:
                  break;
              }
  
          }
  
      // calc matrices
      glm::mat4 scale = glm::scale(glm::mat4(), glm::vec3(1, 1, 1));
      glm::mat4 model = scale * glm::mat4(1.0);
      glm::mat4 MVP = DisplayManager::GetProjectionMatrix() * model;
  
      // send the final matrix over
      GLuint MVPLoc = glGetUniformLocation(program.id, "MVP");
      glUniformMatrix4fv(MVPLoc, 1, GL_FALSE, glm::value_ptr(MVP));
  
      // clear and draw
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      glDrawElements(GL_TRIANGLES, dragonModel.num_indices, GL_UNSIGNED_INT, NULL);
  
      DisplayManager::Swap(); // SDL_GL_SwapWindow()
  }
  
  #undef main
  int main(void)
  {
      // create a display and get the camera
      DisplayManager::Create("yay", 800, 600);
      camera = DisplayManager::GetCamera();
      glClearColor(0, 0, 0, 1);
      DisplayManager::Swap();
  
      // load the dragon model
      load_model(&amp;dragonModel, "dragon.obj");
  
      // load the shader program
      program = ShaderManager::LoadProgram("basicShader.vert", "basicShader.frag");
      ShaderManager::SetCurrentProgram(program);
  
      if(!IsValidProgram(program))
      {
          printf("\ninvalid program detected\n");
      }
  
      // set up the model's VAO and leave it bound
      glEnable(GL_DEPTH_TEST);
      glCullFace(GL_BACK);
  
      GLuint dragonVAO = -1;
      GLuint VBO = -1;
      GLuint EBO = -1;
      glGenVertexArrays(1, &amp;dragonVAO);
      glBindVertexArray(dragonVAO);
      glGenBuffers(1, &amp;VBO);
      glGenBuffers(1, &amp;EBO);
      glBindBuffer(GL_ARRAY_BUFFER, VBO);
      glBufferData(GL_ARRAY_BUFFER, dragonModel.num_vertices * 3 * sizeof(GLfloat), dragonModel.vertices, GL_STATIC_DRAW);
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
      glBufferData(GL_ELEMENT_ARRAY_BUFFER, dragonModel.num_indices * sizeof(GLuint), dragonModel.indices, GL_STATIC_DRAW);
      glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
      glEnableVertexAttribArray(0);
  
      // free the model because we don't need our copy
      free_model(&amp;dragonModel);
  
      // start the event loop
      EventLoop eventLoop;
      eventLoop.SetLoopCallback(&amp;callback);
      eventLoop.Start();
  
      return 0;
  }
  </code></pre>
  
  <p>And here are my shaders:</p>
  
  <p>basicShader.vert</p>
  
  <pre><code>#version 330
  uniform mat4 MVP;
  layout(location = 0) in vec3 in_position;
  out vec4 passed_color;
  void main(void)
  {
      gl_Position = MVP * vec4(in_position, 1.0f);
      passed_color = vec4(normalize(in_position), 1.0f);
  }
  </code></pre>
  
  <p>basicShader.frag</p>
  
  <pre><code>#version 330
  
  in vec4 passed_color;
  
  void main(void)
  {
      gl_FragColor = passed_color;
  }
  </code></pre>
  
  <p><strong>What I have Tried:</strong></p>
  
  <ul>
  <li>Updating Drivers    </li>
  <li>Making sure that the number of indices isn't changing when
  it messes up.</li>
  </ul>
  
  <p>I don't see any updating of model data or changing in draw calls that would make this happen. I am suspicious of glDrawElements, glClear, my matrix updates, and the creation of my context:</p>
  
  <pre><code>void DisplayManager::Create(const char *title, int width, int height)
  {
      SDL_Init(SDL_INIT_VIDEO);
      camera_ = new Camera();
  
      SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
      SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
      SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
      SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
      SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
      SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
      SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
      SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
  
  
      window_ = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
      glContext_ = SDL_GL_CreateContext(window_);
  
      SDL_GL_MakeCurrent(window_, glContext_);
      SDL_GL_SetSwapInterval(1);
  
      glewExperimental = GL_TRUE;
      GLenum err = glewInit();
      if(err != GLEW_OK)
      {
          printf("glew failed to init: %s", glewGetErrorString(err));
      }
  }
  </code></pre>