Search code examples
pythonarraysnumpyopenglpyopengl

OpenGL python drawing circle little detail missing?


I implemented a draw circle function, it's almost done, but this is how it looks like:

def drawCicrcle(x, y, z, radius, numSides):
    numVertices = numSides + 2
    doublePi = 2.0 * math.pi
    circleVerticesX = np.array([], dtype='f')
    circleVerticesY = np.array([], dtype='f')
    circleVerticesZ = np.array([], dtype='f')

    circleVerticesX = np.insert(circleVerticesX, 0, x)
    circleVerticesY = np.insert(circleVerticesX, 0, y)
    circleVerticesZ = np.insert(circleVerticesX, 0, z)


    for i in range(1, numVertices):
        circleVerticesX = np.append(
            circleVerticesX, x + (radius * math.cos(i * doublePi / numSides)))
        circleVerticesY = np.append(
            circleVerticesY, y + (radius * math.sin(i * doublePi / numSides)))
        circleVerticesZ = np.append(circleVerticesZ, z)

    allCircleVertices = np.array([], dtype='f')

    for i in range(0, numVertices):
        allCircleVertices = np.insert(
            allCircleVertices, i*3, circleVerticesX[i])
        allCircleVertices = np.insert(
            allCircleVertices, (i*3) + 1, circleVerticesY[i])
        allCircleVertices = np.insert(
            allCircleVertices, (i*3) + 2, circleVerticesZ[i])

    vboc = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, vboc)
    glBufferData(GL_ARRAY_BUFFER, allCircleVertices, GL_STATIC_DRAW)
    glVertexAttribPointer(0, 3, GL_FLOAT, False,
                          sizeof(ctypes.c_float)*9, ctypes.c_void_p(36))
    glDrawArrays(GL_TRIANGLE_FAN, 0, numVertices)

And I call in my main drawCicrcle(-0.5, 0.5, 0.0, 0.18, 360) What am I missing?


Solution

  • circleVerticesX = np.array([numVertices], dtype='f') doesn't do what you expect it to do. It creates a numpy array with a single element with the value numVertices (see numpy.array).

    Create a list with the vertex coordinates and create a numpy array from the list:

    vertex_list = [...]
    # [...]
    
    allCircleVertices = np.array([vertex_list], dtype='f')
    

    Function drawCicrcle:

    def drawCicrcle(x, y, z, radius, numSides):
        numVertices = numSides + 2
        doublePi = 2.0 * math.pi
    
        vertex_list = [x, y, z]
        for i in range(1, numVertices):
            vertex_list.append(x + (radius * math.cos(i * doublePi / numSides)))
            vertex_list.append(y + (radius * math.sin(i * doublePi / numSides)))
            vertex_list.append(z)
        allCircleVertices = np.array([vertex_list], dtype='f')
    
        vboc = glGenBuffers(1)
        glBindBuffer(GL_ARRAY_BUFFER, vboc)
        glBufferData(GL_ARRAY_BUFFER, allCircleVertices, GL_STATIC_DRAW)
        glVertexAttribPointer(0, 3, GL_FLOAT, False, 3*sizeof(ctypes.c_float), ctypes.c_void_p(0))
        glDrawArrays(GL_TRIANGLE_FAN, 0, numVertices)
    

    Alternatively create an empty numpy array with numVertices*3 elements (see numpy.empty) and assign the vertex coordinates to the fields of the array:

    allCircleVertices = np.array([vertex_list], dtype='f')
    
    allCircleVertices[0:3] = [x, y, z]
    # [...]
    

    Function drawCicrcle:

    def drawCicrcle(x, y, z, radius, numSides):
        numVertices = numSides + 2
        doublePi = 2.0 * math.pi
    
        allCircleVertices = np.empty((numVertices*3), dtype='f')
        allCircleVertices[0:3] = [x, y, z]
        for i in range(1, numVertices):
            vx = x + (radius * math.cos(i * doublePi / numSides))
            vy = y + (radius * math.sin(i * doublePi / numSides))
            allCircleVertices[i*3:i*3+3] = [vx, vy, z]
    
        vboc = glGenBuffers(1)
        glBindBuffer(GL_ARRAY_BUFFER, vboc)
        glBufferData(GL_ARRAY_BUFFER, allCircleVertices, GL_STATIC_DRAW)
        glVertexAttribPointer(0, 3, GL_FLOAT, False, 3*sizeof(ctypes.c_float), ctypes.c_void_p(0))
        glDrawArrays(GL_TRIANGLE_FAN, 0, numVertices)