title: How to draw a triangle with SDL2 and OpenGL?
body: <p>I'm developing a simple application with SDL2 and OpenGL in C++.</p>
  
  <p>The problem is that my program doesn't draw the triangle.</p>
  
  <p>Rect.hpp (The class that draw the triangle):</p>
  
  <pre><code>#ifndef Rect_hpp
  #define Rect_hpp
  
  #include &lt;stdio.h&gt;
  #include &lt;iostream&gt;
  #define GLEW_STATIC
  #include &lt;GL/glew.h&gt;
  #include &lt;SDL2/SDL.h&gt;
  #include "Shaders.hpp"
  
  using namespace std;
  
  extern GLfloat vertices[];
  
  class Rect
  {
  
  public:
   Rect();
   ~Rect();
   void init();
  void draw();
  
  private:
   void bind();
  
   GLuint VAO;
   GLuint VBO;
   GLuint vertexShader;
   GLuint fragmentShader;
   GLuint shaderProgram;
   Shaders shaders;
  
  };
  
  #endif /* Rect_hpp */
  </code></pre>
  
  <p>Rect.cpp:</p>
  
  <pre><code>#include "Rect.hpp"
  
  GLfloat vertices[] = {
  -0.5f, -0.5f, 0.0f,
  0.5f, -0.5f, 0.0f,
  0.0f, 0.5f, 0.0f,
  };
  
  Rect::Rect()
  {
  VBO = NULL;
  vertexShader = NULL;
  fragmentShader = NULL;
  shaderProgram = NULL;
  }
  
  Rect::~Rect()
  {
  glDeleteShader(vertexShader);
  vertexShader = NULL;
  glDeleteShader(fragmentShader);
  fragmentShader = NULL;
  }
  
  void Rect::bind()
  {
  glBindVertexArray(VAO);
  
      glBindBuffer(GL_ARRAY_BUFFER, VBO); //VBO activation
      glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
  
      glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat (GLvoid*)0);
      glEnableVertexAttribArray(0);
  
  glBindVertexArray(0);
  }
  
  void Rect::init()
  {
  //VAO
  glGenVertexArrays(1, &amp;VAO); //VAO creation
  
  //VBO
  glGenBuffers(1, &amp;VBO); //VBO creation
  
  //SHADER
  vertexShader = glCreateShader(GL_VERTEX_SHADER); //vertex shader
  glShaderSource(vertexShader, 1, &amp;shaders.vertexSource, NULL);
  glCompileShader(vertexShader);
  
  fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); //fragment shader
  glShaderSource(fragmentShader, 1, &amp;shaders.fragmentSource, NULL);
  glCompileShader(fragmentShader);
  
  shaderProgram = glCreateProgram(); //shader program
  glAttachShader(shaderProgram, vertexShader);
  glAttachShader(shaderProgram, fragmentShader);
  glLinkProgram(shaderProgram);
  
  bind();
  }
  
  void Rect::draw()
  {
   glUseProgram(shaderProgram);
   glBindVertexArray(VAO);
   glDrawArrays(GL_TRIANGLES, 0, 3);
   glBindVertexArray(0);
  }
  </code></pre>
  
  <p>Game.hpp:</p>
  
  <pre><code>#ifndef Game_hpp
  #define Game_hpp
  
  #include &lt;stdio.h&gt;
  #include &lt;iostream&gt;
  #define GLEW_STATIC
  #include &lt;GL/glew.h&gt;
  #include &lt;SDL2/SDL.h&gt;
  #include &lt;SDL2/SDL_opengl.h&gt;
  #include &lt;OpenGL/gl3.h&gt;
  #include "glm/glm.hpp"
  #include "Rect.hpp"
  
    using namespace glm;
    using namespace std;
  
    class Game
  {
  
  public:
  Game(int width, int height);
  ~Game();
  void run();
  
  private:
  int _width, _height;
  
  void init();
  void loop();
  void input();
  void draw();
  
  SDL_Window* window;
  SDL_GLContext context;
  bool isRunning;
  SDL_Event e;
  Rect* rect;
  
  };
  
  #endif /* Game_hpp */
  </code></pre>
  
  <p>Game.cpp:</p>
  
  <pre><code>#include "Game.hpp"
  
  Game::Game(int width, int height)
  {
   _width = width;
   _height = height;
  
  window = NULL;
  context = NULL;
  
  rect = new Rect();
  
   isRunning = true;
  }
  
   Game::~Game()
   {
   SDL_GL_DeleteContext(context);
   context = NULL;
   SDL_DestroyWindow(window);
   window = NULL;
   SDL_Quit();
   }
  
  void Game::run()
  {
   init();
   loop();
  }
  
  void Game::init()
  {
   //SDL INIT
   SDL_Init(SDL_INIT_EVERYTHING);
  
   //OPENGL ATTRIBUTES
   SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,  SDL_GL_CONTEXT_PROFILE_CORE);
   SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
   SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
   SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
   SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
  
    //WINDOW INIT
    window = SDL_CreateWindow("OpenGL_GAME_TEST",
                            SDL_WINDOWPOS_CENTERED,
                            SDL_WINDOWPOS_CENTERED,
                            _width,
                            _height,
                            SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
  glViewport(0, 0, _width, _height);
  
  //OPENGL CONTEXT INIT
  context = SDL_GL_CreateContext(window);
  
  //GLEW INIT
  glewExperimental = GL_TRUE;
  if(glewInit() != GLEW_OK)
      cout &lt;&lt; "ERROR: GLEW initialization failed!" &lt;&lt; endl;
  
  //CLASSES INIT
  rect-&gt;init();
  
  }
  
  void Game::loop()
  {
  while(isRunning)
  {
      input();
      draw();
  }
  }
  
  void Game::input()
  {
  if(SDL_PollEvent(&amp;e))
  {
  
      if(e.type == SDL_QUIT) isRunning = false;
      if(e.type == SDL_KEYDOWN)
          if(e.key.keysym.sym == SDLK_ESCAPE) isRunning = false;
  
  }
  }
  
  void Game::draw()
  {
  //DRAW...
  glClearColor(0.2f, 0.4f, 0.5f, 1.0f);
  glClear(GL_COLOR_BUFFER_BIT);
  
  rect-&gt;draw();
  
  SDL_GL_SwapWindow(window);
  }
  </code></pre>
  
  <p>Shaders.hpp:</p>
  
  <pre><code>#ifndef Shaders_hpp
  #define Shaders_hpp
  
  #include &lt;stdio.h&gt;
  #include &lt;iostream&gt;
  #include &lt;GL/glew.h&gt;
  
    class Shaders
  {
  
  public:
  Shaders();
  ~Shaders();
  const GLchar* vertexSource;
  const GLchar* fragmentSource;
  
  };
  
  #endif /* Shaders_hpp */
  </code></pre>
  
  <p>Shaders.cpp:</p>
  
  <pre><code>#include "Shaders.hpp"
  
  Shaders::Shaders()
  {
  vertexSource = "#version 330 core \n"
                 "layout (location = 0) in vec3 position; \n"
                 "void main() \n"
                 "{ \n"
                 "    gl_Position = vec4(position, 1.0); \n"
                 "} \n \0";
  
  fragmentSource = "#version 330 core \n"
                   "out vec4 color \n"
                   "void main() \n"
                   "{ \n"
                   "  color = vec4(1.0, 0.5, 0.1, 1.0); \n"
                   "}; \n \0";
   }
  
  Shaders::~Shaders()
  { 
  
  }
  </code></pre>