Hi,
For those looking for a functional answer:
import sys
import moderngl as GL
import numpy
from PyQt6.QtWidgets import QApplication
from PyQt6.QtOpenGLWidgets import QOpenGLWidget
class Main(QOpenGLWidget):
def __init__(self, parent=None):
super().__init__(parent)
def initializeGL(self):
# Set up the OpenGL context using moderngl
self.ctx = GL.create_context()
self.ctx.clear(0, 0, 0)
# Define shaders with error checking
vertex_shader_code = '''
#version 330 core
in vec3 in_vert;
void main() {
gl_Position = vec4(in_vert, 1.0);
}
'''
fragment_shader_code = '''
#version 330 core
out vec4 fragColor;
uniform vec4 color;
void main() {
fragColor = color;
}
'''
# Compile shaders and program
self.program = self.ctx.program(
vertex_shader=vertex_shader_code,
fragment_shader=fragment_shader_code
)
# Check for any shader compilation issues
if not self.program:
print("Shader program failed to compile.")
return
# Define triangle vertices (in normalized device coordinates)
self.vertices = numpy.array([
0.0, 0.5, 0.0, # Top vertex
-0.5, -0.5, 0.0, # Bottom-left vertex
0.5, -0.5, 0.0 # Bottom-right vertex
], dtype='f4')
# Create the buffer for the vertices
self.vbo = self.ctx.buffer(self.vertices)
# Create vertex array object (VAO)
self.vao = self.ctx.simple_vertex_array(self.program, self.vbo, 'in_vert')
# Set the uniform color (Red in this case)
self.program['color'].value = (1.0, 0.0, 0.0, 1.0) # Red # EDITED: 1.0, 1.0, 1.0 is white.
def resizeGL(self, w, h):
# EDITED: Detect framebuffer again after resize.
# To be fair: Claude AI gave me this solution.
fbo = self.ctx.detect_framebuffer()
fbo.use()
self.ctx.viewport = (0, 0, w, h)
def paintGL(self):
# Clear the screen
self.ctx.clear(0.0, 0.0, 0.0)
# Draw the triangle
self.vao.render()
if __name__ == '__main__':
app = QApplication([])
win = Main()
win.resize(800, 600)
win.show()
sys.exit(app.exec())