Search code examples
pythonglutvbopyopenglvao

VBO PyOpenGL Points


I'm working with PyOpenGL and GLUT at the moment and just want to visualize some points on the screen with VBO. I'm pretty new to programming with PyOpenGL, so maybe the code isn't good at all. But should work in my opinion. But I always get just one point. Anyone an idea, why?

Thanks for helping!!

import sys 
import random #for random numbers
from OpenGL.GL import * #for definition of points
from OpenGL.GLU import *
from OpenGL.GLUT import * #for visualization in a window
import numpy as np

AMOUNT = 10
DIMENSION = 3

def changePoints(points):
    for i in range(0, 3*AMOUNT):
        x = random.uniform(-1.0, 1.0)
        points[i]= points[i]*x
    print(points)
    return points

def displayPoints(points):
    vbo=GLuint(0) # init the Buffer in Python!
    glGenBuffers(1, vbo) # generate a buffer for the vertices
    glBindBuffer(GL_ARRAY_BUFFER, vbo) #bind the vertex buffer
    glBufferData(GL_ARRAY_BUFFER,sys.getsizeof(points), points, GL_STREAM_DRAW) 
    glBindBuffer(GL_ARRAY_BUFFER, vbo) #bind the vertex buffer

    glEnableClientState(GL_VERTEX_ARRAY) # enable Vertex Array
    glVertexPointer(DIMENSION, GL_FLOAT,0, ctypes.cast(0, ctypes.c_void_p))
    glBindBuffer(GL_ARRAY_BUFFER, vbo) #bind the vertex buffer
    glDrawArrays(GL_POINTS, 0, AMOUNT) 
    glDisableClientState(GL_VERTEX_ARRAY) # disable the Vertex Array
    glDeleteBuffers(1, vbo)

##creates Points 
def Point(): 

    points = np.arange(AMOUNT*3)
    np.ascontiguousarray(points, dtype = np.float32)

    points = changePoints(points)

    #Visualization
    displayPoints(points)


##clears the color and depth Buffer, call Point() and swap the buffers of the current window
def display():
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    Point()
    glutSwapBuffers() 

def main():
    ##initials GLUT
    glutInit(sys.argv) 
    #sets the initial display mode (selects a RGBA mode window; selects a double buffered window; selects a window with a depth buffer)
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH)
    #defines the size of the Window
    glutInitWindowSize(800, 1600) 
    #creates a window with title
    glutCreateWindow(b'Points') #!string as title is causing a error, because underneath the PyOpenGL call is an old-school C function expecting ASCII text. Solution: pass the string in byte format.
    glutDisplayFunc(display) #sets the display callback for the current window.
    glutMainLoop() #enters the GLUT event processing loop. 

main()

Solution

  • If you don't use any projection matrix, then you have to set up the vertex coordinates of the points in normalized device space, which is from (-1, -1, -1) to (1, 1, 1). This volume is projected to the viewport.

    To solve your issue, points has to be an array of elements with data type np.float32:

    def Point(): 
    
        points = np.arange(AMOUNT*3, dtype = np.float32)
        points = changePoints(points)
    
        #Visualization
        displayPoints(points)
    

    and the coordinates of the points have to be in the range [-1.0, 1.0]:

    def changePoints(points):
    for i in range(len(points)):
        points[i] = random.uniform(-1.0, 1.0)
    print(points)
    return points