UPDATE: you may be interested in the Vispy library, which provides easier and more Pythonic access to OpenGL.
PyOpenGL, the 'OpenGL' package when installed, provides GL, GLES1, GLES2, GLES3, GLUT, GLU, GLE, WGL, EGL and GLX subpackages; OpenGLaccelerate, a cython coded accelerator module for PyOpenGL, optional, but recommended where available The code for OpenGLaccelerate is in the core PyOpenGL repository, but is distributed as a separate Python.
Welcome back!Through normal installation of PyOpenGL via pip install pyopengl and working with GLUT can be hard to set manually in windows.This video shows y. Home; Docs; Install; PyOpenGL 3.x The Python OpenGL Binding About PyOpenGL. PyOpenGL is the most common cross platform Python binding to OpenGL and related APIs. The binding is created using the standard ctypes library, and is provided under an extremely liberal BSD-style Open-Source license. Originally developed by Silicon Graphics in the early '90s, OpenGL® has become the most widely-used open graphics standard in the world. NVIDIA supports OpenGL and a complete set of OpenGL extensions, designed to give you maximum performance on our GPUs. NVIDIA continues to support OpenGL as well through technical papers and our large set of examples on our NVIDIA Graphics SDK.
OpenGL is a widely used open and cross-platform library for real-time 3D graphics, developed more than twenty years ago. It provides a low-level API that allows the developer to access the graphics hardware in an uniform way. It is the platform of choice when developing complex 2D or 3D applications that require hardware acceleration and that need to work on different platforms. It can be used in a number of languages including C/C++, C#, Java, Objective-C (used in iPhone and iPad games), Python, etc. In this article, I'll show how OpenGL can be used with Python (thanks to the PyOpenGL library) to efficiently render 2D graphics.
One needs Python with theNumpy,PyOpenGL, andPyQt4 libraries. OnWindows, binary installers can be foundon this webpage.
In addition, the mostrecent drivers of the system graphics cards are needed, so that the latestimplementation of OpenGL is available. In particular, we'll make use ofvertex buffer objects (VBOs),that are available in the core implementationstarting from OpenGL version 1.5 (which appeared in 2003). Graphics cards thatwere shipped after this date should have drivers that support VBOs. However,it is possible that the drivers installed on the system do not support arecent version of OpenGL.
For instance, on Windows, I had some issues with the default drivers of a 2009graphics cards: OpenGL 1.1 was the only supported version. The reason is thatWindows (starting from Vista) can use a sort of generic driver based on theWindows Display Driver Model (WDDM)when the constructor drivers are not foundor not available. Now, the WDDM drivers tend to privilegeDirectX (Microsoft'sown graphics library, concurrent to OpenGL) rather than OpenGL, such that onlyvery old versions of OpenGL are supported on those drivers. In order to makethings work, one needs to find the constructor drivers and force theirinstallation. It can be a bit painful.
In brief, if you have an error message mentioning OpenGL and buffer objects whenrunning the script below, ensure that the graphics card drivers are the rightones. An extremely useful tool to check the OpenGL capabilities of thegraphics card isOpenGL Extensions Viewer. It works onWindows, Linux, and iOS.
We'll define aQtwidget that displays points at random positions in the window.This widget will derive from
QGLWidget,a Qt widget that offers access tothe OpenGL API for rendering. Three methods at least need to be overridenin the derived class:
initializeGL(): make here calls to OpenGL initialization commands. It is also the place for creating vertex buffer objects and populating them with some data.
paintGL(): make here calls to OpenGL rendering commands. It is called whenever the window needs to be redrawn.
resizeGL(w, h): make here calls related to camera and viewport. It is called whenever the size of the widget is changed (the new widget size are passed as parameters to this method).
Vertex Buffer Objects
The most efficient way of rendering data is to minimize the datatransfers from system memory to GPU memory, and to minimize the number of callsto OpenGL rendering commands. A convenient way for doing this is to useVertex Buffer Objects.They allow to allocate memory on the GPU, load data on the GPUonce (or several times if the data changes), and render itefficiently since the data stays on the GPU between consecutives calls to
paintGL(). PyOpenGL integrates a module to easily create and use VBOs:
Painting with VBOs
OpenGL can render primitives like points, lines, and convex polygons.The
glVertexPointerfunctions configure the VBOfor rendering, and the
glDrawArraysfunction draws primitives from thebuffer stored in GPU memory. Other drawing commands that can be used witha VBO include
glMultiDrawArraysfor plotting several independent primitivesfrom a single VBO (which is more efficient, but less flexible, than usingseveral VBOs). Indexed drawing is also possible and allows to use verticesin arbitrary order, and to reuse vertices several times during rendering.The relevant functions are
Color can be specified either before calling the rendering commands, withthe function
glColor,or by creating a special VBO for colors, containingthe colors of every point. The relevant functions are
glEnableClientState(GL_COLOR_ARRAY). A variant consists in packing thecolors with the vertices, i.e. having 5 numbers per point in a single VBO(x, y coordinates and R, V, B color components).See some details here.
Note: apparently, in OpenGL, usingsingle precision floating point numbersis better than usingdouble precision float point numbers.The graphics card may not indeed support the latter format. I used doubles inan early version of this post and I had some nasty memory access violationcrashes in particular cases. They disappeared when I switched to floats. Ifthis is helpful to anyone...
Setting orthographic projection for 2D rendering
resizeGL method sets the geometric projection used forrasterization.Since we're only interested in 2D rendering in this article, we're usingorthographic projectionwith the
glViewportfunctionallows to specify the part of the screen used for the subsequent renderingcommands. Here we just tell OpenGL to draw within the entire window.
Setting the PyQt widget
Here we use PyQt as a GUI window system. To show a window on the screen anduse our OpenGL widget, we first need to define a Qt main window, put theOpenGL widget inside, and finally create a Qt application to host the mainwindow.
Pyopengl Load Obj
Here is the full script.
Here are some related interesting links: