Only part of the sphere is drawn

Hi guys. So I’m currently working on a project where I have to generate spheres. So far, I’ve done just that, however, there is a problem with my program. The full sphere isn’t drawn and I’ve been stuck on it for several hours. Below is the wireframe showing my problem

As you can see, I’ve gotten the majority of the sphere to draw but there is one section missing. For background information, the method I used to generate the sphere is by creating an octahedron, passing the vertices to tessellation shaders, and then outputting it, this being the easiest method I’ve found for generating spheres. The code is down below.

Octahedron vertices and indices as well as the buffers and draw call

  #define NUM_PATCH_PTS 3
  unsigned int draw_calls = 3;
  float vertices[] = {
      //top-north-east
       0.0,  1.0,  0.0,
       0.0,  0.0,  1.0,
       1.0,  0.0,  0.0,

      //top-north-west
       0.0,  1.0,  0.0,
      -1.0,  0.0,  0.0,
       0.0,  0.0,  1.0,

      //top-south-west
       0.0,  1.0,  0.0,
       0.0,  0.0, -1.0,
      -1.0,  0.0,  0.0,

      //top-south-east
       0.0,  1.0,  0.0,
       1.0,  0.0,  0.0,
       0.0,  0.0, -1.0,

      //bottom-north-east
       0.0, -1.0,  0.0,
       1.0,  0.0,  0.0,
       0.0,  0.0,  1.0,

      //bottom-north-west
       0.0, -1.0,  0.0,
       0.0,  0.0,  1.0,
      -1.0,  0.0,  0.0,

      //bottom-south-west
       0.0, -1.0,  0.0,
      -1.0,  0.0,  0.0,
       0.0,  0.0, -1.0,

      //bottom-south-east
       0.0, -1.0,  0.0,
       0.0,  0.0, -1.0,
       1.0,  0.0,  0.0
};

  unsigned int indices[] = {
      // first triangle
      0, 1, 2,
      // second triangle
      3, 4, 5,
      // third triangle
      6, 7, 8,
      // fourth triangle
      9, 10, 11,
      // fifth triangle
      12, 13, 14,
      // sixth triangle
      15, 16, 17,
      // seventh triangle
      18, 19, 20,
      // eighth triangle
      21, 22, 23
  };

  unsigned int vbo, vao, ebo;
  glGenVertexArrays(1, &vao);
  glGenBuffers(1, &vbo);
  glGenBuffers(1, &ebo);

  glBindVertexArray(vao);

  // upload vertex data to gpu
  glBindBuffer(GL_ARRAY_BUFFER, vbo);
  glBufferData(GL_ARRAY_BUFFER, sizeof(vertices) * sizeof(double), &vertices[0], GL_STATIC_DRAW);

  // upload index data to gpu
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices) * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);

  // position attribute
  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
  glEnableVertexAttribArray(0);

  // normal attribute
  glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)(3 * sizeof(float)));
  glEnableVertexAttribArray(1);

  // max tessellation points / patches
  glPatchParameteri(GL_PATCH_VERTICES, NUM_PATCH_PTS);
  glBindVertexArray(vao);
  glDrawArrays(GL_PATCHES, 0, draw_calls*draw_calls*NUM_PATCH_PTS);

vertex shader

#version 450 core
// position of the object
layout (location = 0) in vec3 pos;
layout (location = 1) in vec3 vert;

// vertices to make the sphere
out vec3 vert_coord;

void main()
{
    // position object
    gl_Position = vec4(pos, 1.0f);
    // put the vertices into a different vector
    vert_coord = vert;
}

Tessellation control

#version 450 core

// specify control points per output per patch
// control size of input and output arrays
layout(vertices=3) out;
// input from vertex shader
in vec3 vert_coord[];
// output to evaluation shader
out vec3 vertex_coord[];

// for tessellation
uniform mat4 view;
uniform mat4 model;

void main()
{
    // pass attributes through
    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
    vertex_coord[gl_InvocationID] = vert_coord[gl_InvocationID];

    // control tessellation
    if(gl_InvocationID==0)
    {
        // dynamic tessellation
        // first: define rendering constants to control tessellation
        const float MIN_TESS_LEVEL = 4;
        const float MAX_TESS_LEVEL = 64;
        const float MIN_DISTANCE = 20;
        const float MAX_DISTANCE = 800;
        // second: transform each vertex into each eye
        vec4 eye_space_pos_1 = view * model * gl_in[0].gl_Position;
        vec4 eye_space_pos_2 = view * model * gl_in[1].gl_Position;
        vec4 eye_space_pos_3 = view * model * gl_in[2].gl_Position;
        // third: distance from camera scaled between 0 and 1
        float distance_1 = clamp((abs(eye_space_pos_1.z)-MIN_DISTANCE)/(MAX_DISTANCE-MIN_DISTANCE), 0.0, 1.0);
        float distance_2 = clamp((abs(eye_space_pos_2.z)-MIN_DISTANCE)/(MAX_DISTANCE-MIN_DISTANCE), 0.0, 1.0);
        float distance_3 = clamp((abs(eye_space_pos_3.z)-MIN_DISTANCE)/(MAX_DISTANCE-MIN_DISTANCE), 0.0, 1.0);
        // fourth: interpolate edge tessellation level based on closer vertex
        float tess_level_1 = mix(MAX_TESS_LEVEL, MIN_TESS_LEVEL, min(distance_3, distance_1));
        float tess_level_2 = mix(MAX_TESS_LEVEL, MIN_TESS_LEVEL, min(distance_1, distance_2));
        float tess_level_3 = mix(MAX_TESS_LEVEL, MIN_TESS_LEVEL, min(distance_2, distance_1));
        // fifth: set the corresponding outer tessellation levels
        gl_TessLevelOuter[0] = tess_level_1;
        gl_TessLevelOuter[1] = tess_level_2;
        gl_TessLevelOuter[2] = tess_level_3;
        // sixth: set the inner tessellation levels
        gl_TessLevelInner[0] = max(tess_level_2, tess_level_1);
        gl_TessLevelInner[1] = max(tess_level_1, tess_level_3);
    }
}

Tessellation eval

#version 450 core

// from control shader
layout(triangles, equal_spacing, cw) in;

// input from control shader
in vec3 vertex_coord[];
// output vec
out vec3 vert;

// allows for object transformations and for movement
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
    // make it into a sphere
    vec3 u = gl_TessCoord.x * vertex_coord[0];
    vec3 v = gl_TessCoord.y * vertex_coord[1];
    vec3 w = gl_TessCoord.z * vertex_coord[2];
    vec3 pos = normalize(u + v + w);

    // output patch point position in clip space
    gl_Position = projection * view * model * vec4(pos, 1.0);
}

Hey future programmers, assuming alot of you are newbies. Anyway, I finally figured it out. The problem was the octahedron coordinates I was given were wrong. Someone on a different forum figured that out and then let me figure out what were the right coordinates. Here are the correct coordinates and then how the sphere looks like right now

    float vertices[] = {
       //top-north-east
       0.0f, 1.0f,  0.0f,
       0.0f,  0.0f,  1.0f,
       1.0f,  0.0f,  0.0f,
      //top-north-west
       0.0f,  1.0f,  0.0f,
      -1.0f,  0.0f,  0.0f,
       0.0f,  0.0f,  1.0f,

      //top-south-west
       0.0f,  1.0f,  0.0f,
       0.0f,  0.0f, -1.0f,
      -1.0f,  0.0f,  0.0f,

      //top-south-east
       0.0f, -1.0f,  0.0f,
       1.0f,  0.0f,  0.0f,
       0.0f,  0.0f, -1.0f,

      //bottom-north-east
       0.0f, -1.0f,  0.0f,
       1.0f,  0.0f,  0.0f,
       0.0f,  0.0f,  1.0f,

      //bottom-north-west
       0.0f, -1.0f,  0.0f,
       0.0f,  0.0f,  1.0f,
      -1.0f,  0.0f,  0.0f,

      //bottom-south-west
       0.0f, -1.0f,  0.0f,
      -1.0f,  0.0f,  0.0f,
       0.0f,  0.0f, -1.0f,

      //bottom-south-east
       0.0f, 1.0f,  0.0f,
       0.0f,  0.0f, -1.0f,
       1.0f,  0.0f,  0.0f
};

1 Like

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.