title: How can I draw a circle in OpenGL Core 3.3 with orthographic projection?
body: <p>I'm a complete beginner to OpenGL programming and am trying to follow the Breakout tutorial at <a href="https://learnopengl.com/In-Practice/2D-Game/Collisions/Ball" rel="nofollow noreferrer">learnopengl.com</a> but would like to draw the ball as an actual circle, instead of using a textured quad like Joey suggests. However, every result that Google throws back at me for "draw circle opengl 3.3" or similar phrases seems to be at least a few years old, and using even-older-than-that versions of the API :-(</p>
  
  <p>The closest thing that I've found is <a href="https://stackoverflow.com/questions/54583368/how-to-draw-multiple-objects-in-opengl-using-multiple-vao-and-vbo">this SO question</a>, but of course the OP just <strong>had</strong> to use a custom <code>VertexFormat</code> object to abstract some of the details, without sharing his/her implementation of such! Just my luck! :P</p>
  
  <p>There's also <a href="https://www.youtube.com/watch?v=YDCSKlFqpaU" rel="nofollow noreferrer">this YouTube tutorial</a> that uses a seemingly-older version of the API, but copying the code verbatim (except for the last few lines which is where the code looks old) still got me nowhere.</p>
  
  <p>My version of <a href="https://learnopengl.com/In-Practice/2D-Game/Rendering-Sprites" rel="nofollow noreferrer"><code>SpriteRenderer::initRenderData()</code></a> from the tutorial:</p>
  
  <pre><code>void SpriteRenderer::initRenderData() {
      GLuint vbo;
  
      auto attribSize = 0;
      GLfloat* vertices = nullptr;
  
      // Determine whether this sprite is a circle or
      // quad and setup the vertices array accordingly
      if (!this-&gt;isCircle) {
          attribSize = 4;
          vertices = new GLfloat[24] {...}   // works for rendering quads
      } else {
          // This code is adapted from the YouTube tutorial that I linked
          // above and is where things go pear-shaped for me...or at least
          // **not** circle-shaped :P
          attribSize = 3;
  
          GLfloat x = 0.0f;
          GLfloat y = 0.0f;
          GLfloat z = 0.0f;
          GLfloat r = 100.0f;
  
          GLint numSides = 6;
          GLint numVertices = numSides + 2;
  
          GLfloat* xCoords = new GLfloat[numVertices];
          GLfloat* yCoords = new GLfloat[numVertices];
          GLfloat* zCoords = new GLfloat[numVertices];
  
          xCoords[0] = x;
          yCoords[0] = y;
          zCoords[0] = z;
  
          for (auto i = 1; i &lt; numVertices; i++) {
              xCoords[i] = x + (r * cos(i * (M_PI * 2.0f) / numSides));
              yCoords[i] = y + (r * sin(i * (M_PI * 2.0f) / numSides));
              zCoords[i] = z;
          }
  
          vertices = new GLfloat[numVertices * 3];
          for (auto i = 0; i &lt; numVertices; i++) {
              vertices[i * 3] = xCoords[i];
              vertices[i * 3 + 1] = yCoords[i];
              vertices[i * 3 + 2] = zCoords[i];
          }
      }
  
      // This is where I go back to the learnopengl.com code. Once
      // again, the following works for quads but not circles!
      glGenVertexArrays(1, &amp;vao);
      glGenBuffers(1, &amp;vbo);
  
      glBindBuffer(GL_ARRAY_BUFFER, vbo);
      glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(
          GLfloat), vertices, GL_STATIC_DRAW);
  
      glBindVertexArray(vao);
      glEnableVertexAttribArray(0);
  
      glVertexAttribPointer(0, attribSize, GL_FLOAT, GL_FALSE,
          attribSize * sizeof(GLfloat), (GLvoid*)0);
      glBindBuffer(GL_ARRAY_BUFFER, 0);
      glBindVertexArray(0);
  }
  </code></pre>
  
  <p>And here's the <a href="https://learnopengl.com/In-Practice/2D-Game/Rendering-Sprites" rel="nofollow noreferrer"><code>SpriteRenderer::DrawSprite()</code></a> method (the only difference from the original being lines 24 - 28):</p>
  
  <pre><code>void SpriteRenderer::Draw(vec2 position, vec2 size, GLfloat rotation, vec3 colour) {
      // Prepare transformations
      shader.Use();
  
      auto model = mat4(1.0f);
      model = translate(model, vec3(position, 0.0f));
  
      model = translate(model, vec3(0.5f * size.x, 0.5f * size.y, 0.0f));   // Move origin of rotation to center
      model = rotate(model, rotation, vec3(0.0f, 0.0f, 1.0f));              // Rotate quad
      model = translate(model, vec3(-0.5f * size.x, -0.5f * size.y, 0.0f)); // Move origin back
  
      model = scale(model, vec3(size, 1.0f)); // Lastly, scale
  
      shader.SetMatrix4("model", model);
  
      // Render textured quad
      shader.SetVector3f("spriteColour", colour);
  
      glActiveTexture(GL_TEXTURE0);
      texture.Bind();
  
      glBindVertexArray(vao);
  
      if (!isCircular) {
          glDrawArrays(GL_TRIANGLES, 0, 6);
      } else {
          glDrawArrays(GL_TRIANGLE_FAN, 0, 24);  // also tried "12" and "8" for the last param, to no avail
      }
  
      glBindVertexArray(0);
  }
  </code></pre>
  
  <p>And finally, the shaders (different to the ones used for quads):</p>
  
  <pre><code>// Vertex shader
  #version 330 core
  
  layout (location = 0) in vec3 position;
  
  uniform mat4 model;
  uniform mat4 projection;
  
  void main() {
      gl_Position = projection * model *
          vec4(position.xyz, 1.0f);
  }
  
  // Fragment shader
  #version 330 core
  
  out vec4 colour;
  
  uniform vec3 spriteColour;
  
  void main() {    
      colour = vec4(spriteColour, 1.0);
  }
  </code></pre>
  
  <p>P.S. I know I could just use a quad but I'm trying to learn how to draw <strong>all</strong> primitives in OpenGL, not just quads and triangles (thanks anyway Joey)!</p>
  
  <p>P.P.S I just realised that the learnopengl.com site has a whole section devoted to debugging OpenGL apps, so I set that up but to no avail :-( I don't think the error handling is supported by my driver (Intel UHD Graphics 620 latest driver) since the <code>GL_CONTEXT_FLAG_DEBUG_BIT</code> was not set after following the instructions:</p>
  
  <blockquote>
    <p>Requesting a debug context in GLFW is surprisingly easy as all we have to do is pass a hint to GLFW that we'd like to have a debug output context. We have to do this before we call glfwCreateWindow:</p>
    
    <p>glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);  </p>
    
    <p>Once we initialize GLFW we should have a debug context if we're using OpenGL version 4.3 or higher, or else we have to take our chances and hope the system is still able to request a debug context. Otherwise we have to request debug output using its OpenGL extension(s).</p>
    
    <p>To check if we successfully initialized a debug context we can query OpenGL:</p>
    
    <p>GLint flags; glGetIntegerv(GL_CONTEXT_FLAGS, &amp;flags);</p>
    
    <p>if (flags &amp; GL_CONTEXT_FLAG_DEBUG_BIT) {
        // initialize debug output 
    }</p>
  </blockquote>
  
  <p>That <code>if</code> statement is never entered into!</p>