B19 - openGL
OpenGL
- a cross-language application programming interface (API) for graphics rendering
Windowing
- it is window and OS independent and does not provide a window management facility
- here, PyQt will be used as the windows manager
import sys
from OpenGL import GL
from PyQt6.QtWidgets import QApplication, QMainWindow, QOpenGLWidget
class glwidget(QOpenGLWidget):
"""
opengl widget that displays a simple blue background.
inherits from qopenglwidget.
"""
def __init__(self, parent=None):
"""initialize the gl widget """
super().__init__(parent)
self.parent = parent ## store reference to parent if needed
def initializegl(self):
"""called once to initialize the opengl context"""
GL.glClearColor(0.0, 0.0, 1.0, 0.0) ## blue background
def paintgl(self):
"""called whenever the widget needs to be repainted"""
GL.glClear(GL.GL_COLOR_BUFFER_BIT) ## clear the color buffer
def resizegl(self, width, height):
"""called when the widget is resized"""
print(f"the size of the gl widget is ({width}, {height})")
class mainwindow(QMainWindow):
"""
main window that holds the opengl widget.
inherits from qmainwindow.
"""
def __init__(self):
"""initialize the main window"""
super().__init__()
self.resize(500, 500) ## initial window size
self.setWindowTitle('windowing')
## create opengl widget and set as central widget
self.glwidget = glwidget(self)
self.setCentralWidget(self.glwidget)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = mainwindow()
window.show()
sys.exit(app.exec())
shaders
shader
- a user-defined programming language designed to run on some stage of a graphics processor
- written in the OpenGL Shading Language (GLSL), a C-like language used to program the transformation and fragment stages of the pipeline
- a program combines multiple shader stages into a single linked whole
import sys
from OpenGL import GL
import OpenGL.GL.shaders as shaders
from PyQt6 import QtOpenGLWidgets, QtWidgets
VERTEX_SHADER = """
#version 330
const vec2 vertices[4] = vec2[4](vec2(-0.8, -0.8), vec2(0.8, -0.8),
vec2(-0.8, 0.8), vec2(0.8, 0.8));
void main()
{
gl_Position = vec4(vertices[gl_VertexID], 0.0, 1.0);
}
"""
FRAGMENT_SHADER = """
#version 330
out vec4 colour;
void main(){
colour = vec4(0, 0, 1, 1);
}
"""
class GLWidget(QtOpenGLWidgets.QOpenGLWidget):
def __init__(self, parent=None):
self.parent = parent
super().__init__(parent)
def initializeGL(self):
GL.glClearColor(0.0, 1.0, 0.0, 0.0)
# Create and compile our GLSL program from the shaders
self.program_id = shaders.compileProgram(shaders.compileShader(VERTEX_SHADER, GL.GL_VERTEX_SHADER),
shaders.compileShader(FRAGMENT_SHADER, GL.GL_FRAGMENT_SHADER))
def paintGL(self):
GL.glClear(GL.GL_COLOR_BUFFER_BIT)
# Use our shader
GL.glUseProgram(self.program_id)
GL.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.resize(500, 500)
self.setWindowTitle('Basic Shader')
self.glWidget = GLWidget(self)
self.setCentralWidget(self.glWidget)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
uniform
- global shader variable declared with 'uniform' storage qualifier