Python OpenGL compatibility test

I’m toying with some sort of plugin idea, but I’d like to know how well code works on different platforms before committing much of my to new project.

Easiest way for me, to test multiple platforms fast is to ask help from other coders.

So… it would be nice if you could copy & paste code to Krita Scripter, and test if code runs. :slight_smile:

from PyQt5.QtCore import QTimer
from PyQt5.QtGui import (
        QOpenGLVersionProfile, QSurfaceFormat,
        QOpenGLShader, QOpenGLShaderProgram)
from PyQt5.QtWidgets import QOpenGLWidget

_vertex_code = """\
#version 410 core

void main(void) {
    vec2 pos;
    pos = 2.0 * vec2(gl_VertexID % 2, gl_VertexID / 2) - 1.0;
    gl_Position = vec4(pos.x, pos.y, 0.0, 1.0);
}"""

# https://www.shadertoy.com/view/4dsGzH
_fragment_code = """\
#version 410 core

uniform float iTime;
out vec4 out_color;

vec3 COLOR1 = vec3(0.0, 0.0, 0.3);
vec3 COLOR2 = vec3(0.5, 0.0, 0.0);
float BLOCK_WIDTH = 0.01;

void main(void) {
    vec2 uv = gl_FragCoord.xy / vec2(800.0, 600.0);

    vec3 final_color = vec3(1.0);
    vec3 bg_color = vec3(0.0);
    vec3 wave_color = vec3(0.0);

    float c1 = mod(uv.x, 2.0 * BLOCK_WIDTH);
    c1 = step(BLOCK_WIDTH, c1);
    float c2 = mod(uv.y, 2.0 * BLOCK_WIDTH);
    c2 = step(BLOCK_WIDTH, c2);

    bg_color = mix(uv.x * COLOR1, uv.y * COLOR2, c1 * c2);

    float wave_width = 0.01;
    uv  = -1.0 + 2.0 * uv;
    uv.y += 0.1;
    for(float i = 0.0; i < 10.0; i++) {
        uv.y += (0.07 * sin(uv.x + i/7.0 + iTime));
        wave_width = abs(1.0 / (150.0 * uv.y));
        wave_color += vec3(wave_width * 1.9, wave_width, wave_width * 1.5);
    }
    final_color = bg_color + wave_color;
    out_color = vec4(final_color, 1.0);
}"""

class MyViewport(QOpenGLWidget):
    def initializeGL(self):
        self._iTime = 0.0
        context = self.context()
        profile = QOpenGLVersionProfile()
        profile.setVersion(4, 1)
        profile.setProfile(QSurfaceFormat.CoreProfile)
        self._gl = context.versionFunctions(profile)
        # shader_program
        vert = QOpenGLShader(QOpenGLShader.Vertex)
        vert.compileSourceCode(_vertex_code)
        frag = QOpenGLShader(QOpenGLShader.Fragment)
        frag.compileSourceCode(_fragment_code)
        self._prog = QOpenGLShaderProgram(context)
        self._prog.addShader(vert)
        self._prog.addShader(frag)
        self._prog.link()
        self._timer = QTimer(self)
        self._timer.timeout.connect(self.update)
        self._timer.start(int(1000.0 / 60.0))

    def paintGL(self):
        self._iTime += 0.01
        self._prog.bind()
        self._prog.setUniformValue("iTime", self._iTime)
        gl = self._gl
        gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4)

    def resizeGL(self, width, height):
        self._gl.glViewport(0, 0, width, height)

view = MyViewport()
view.show()

End result should look something like:


/AkiR

Hi

on my side, I got this error:

AttributeError
Python 3.8.1: /usr/bin/python3
Tue Dec  8 21:18:13 2020

A problem occurred in a Python script.  Here is the sequence of
function calls leading up to the error, in the order they occurred.

 /home/grum/Applications/Images/Krita/<string> in paintGL(self=<__main__.MyViewport object>)

AttributeError: 'NoneType' object has no attribute 'glDrawArrays'
    __cause__ = None
    __class__ = <class 'AttributeError'>
    __context__ = None
    __delattr__ = <method-wrapper '__delattr__' of AttributeError object>
    __dict__ = {}
    __dir__ = <built-in method __dir__ of AttributeError object>
    __doc__ = 'Attribute not found.'
    __eq__ = <method-wrapper '__eq__' of AttributeError object>
    __format__ = <built-in method __format__ of AttributeError object>
    __ge__ = <method-wrapper '__ge__' of AttributeError object>
    __getattribute__ = <method-wrapper '__getattribute__' of AttributeError object>
    __gt__ = <method-wrapper '__gt__' of AttributeError object>
    __hash__ = <method-wrapper '__hash__' of AttributeError object>
    __init__ = <method-wrapper '__init__' of AttributeError object>
    __init_subclass__ = <built-in method __init_subclass__ of type object>
    __le__ = <method-wrapper '__le__' of AttributeError object>
    __lt__ = <method-wrapper '__lt__' of AttributeError object>
    __ne__ = <method-wrapper '__ne__' of AttributeError object>
    __new__ = <built-in method __new__ of type object>
    __reduce__ = <built-in method __reduce__ of AttributeError object>
    __reduce_ex__ = <built-in method __reduce_ex__ of AttributeError object>
    __repr__ = <method-wrapper '__repr__' of AttributeError object>
    __setattr__ = <method-wrapper '__setattr__' of AttributeError object>
    __setstate__ = <built-in method __setstate__ of AttributeError object>
    __sizeof__ = <built-in method __sizeof__ of AttributeError object>
    __str__ = <method-wrapper '__str__' of AttributeError object>
    __subclasshook__ = <built-in method __subclasshook__ of type object>
    __suppress_context__ = False
    __traceback__ = <traceback object>
    args = ("'NoneType' object has no attribute 'glDrawArrays'",)
    with_traceback = <built-in method with_traceback of AttributeError object>

The above is a description of an error in a Python program.  Here is
the original traceback:

Traceback (most recent call last):
  File "<string>", line 79, in paintGL
AttributeError: 'NoneType' object has no attribute 'glDrawArrays'

In (linux) console, I have this additional message:

QOpenGLShader::link: error: linking with uncompiled/unspecialized shadererror: linking with uncompiled/unspecialized shader
QOpenGLShaderProgram::uniformLocation(iTime): shader program is not linked

Information about environment:

Krita
  Version: 4.4.1

Qt
  Version (compiled): 5.12.9
  Version (loaded): 5.12.9

OS Information
  Build ABI: x86_64-little_endian-lp64
  Build CPU: x86_64
  CPU: x86_64
  Kernel Type: linux
  Kernel Version: 4.19.0-12-amd64
  Pretty Productname: Debian GNU/Linux 10 (buster)
  Product Type: debian
  Product Version: 10


OpenGL Info
 
  Vendor:  "Intel Open Source Technology Center" 
  Renderer:  "Mesa DRI Intel(R) HD Graphics 520 (Skylake GT2) " 
  Version:  "3.0 Mesa 18.3.6" 
  Shading language:  "1.30" 
  Requested format:  QSurfaceFormat(version 3.0, options QFlags<QSurfaceFormat::FormatOption>(DeprecatedFunctions), depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize 8, alphaBufferSize 8, stencilBufferSize 8, samples -1, swapBehavior QSurfaceFormat::DoubleBuffer, swapInterval 0, colorSpace QSurfaceFormat::DefaultColorSpace, profile  QSurfaceFormat::CompatibilityProfile) 
  Current format:    QSurfaceFormat(version 3.0, options QFlags<QSurfaceFormat::FormatOption>(DeprecatedFunctions), depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize 8, alphaBufferSize 8, stencilBufferSize 8, samples -1, swapBehavior QSurfaceFormat::DoubleBuffer, swapInterval 0, colorSpace QSurfaceFormat::DefaultColorSpace, profile  QSurfaceFormat::NoProfile) 
     Version: 3.0
     Supports deprecated functions true 
     is OpenGL ES: false 

QPA OpenGL Detection Info 
  supportsDesktopGL: true 
  supportsOpenGLES: true 
  isQtPreferOpenGLES: false 

Grum999

I’ll try on my development computer later to see if I have the same errors or not

Grum999

I am on W10 and I got a different message it seems.

AttributeError
Python 3.8.1: C:\Program Files\Krita (x64)\bin\krita.exe
Tue Dec  8 20:36:02 2020

A problem occurred in a Python script.  Here is the sequence of
function calls leading up to the error, in the order they occurred.

 C:\Program Files\Krita (x64)\<string> in resizeGL(self=<__main__.MyViewport object>, width=640, height=480)

AttributeError: 'NoneType' object has no attribute 'glViewport'
    __cause__ = None
    __class__ = <class 'AttributeError'>
    __context__ = None
    __delattr__ = <method-wrapper '__delattr__' of AttributeError object>
    __dict__ = {}
    __dir__ = <built-in method __dir__ of AttributeError object>
    __doc__ = 'Attribute not found.'
    __eq__ = <method-wrapper '__eq__' of AttributeError object>
    __format__ = <built-in method __format__ of AttributeError object>
    __ge__ = <method-wrapper '__ge__' of AttributeError object>
    __getattribute__ = <method-wrapper '__getattribute__' of AttributeError object>
    __gt__ = <method-wrapper '__gt__' of AttributeError object>
    __hash__ = <method-wrapper '__hash__' of AttributeError object>
    __init__ = <method-wrapper '__init__' of AttributeError object>
    __init_subclass__ = <built-in method __init_subclass__ of type object>
    __le__ = <method-wrapper '__le__' of AttributeError object>
    __lt__ = <method-wrapper '__lt__' of AttributeError object>
    __ne__ = <method-wrapper '__ne__' of AttributeError object>
    __new__ = <built-in method __new__ of type object>
    __reduce__ = <built-in method __reduce__ of AttributeError object>
    __reduce_ex__ = <built-in method __reduce_ex__ of AttributeError object>
    __repr__ = <method-wrapper '__repr__' of AttributeError object>
    __setattr__ = <method-wrapper '__setattr__' of AttributeError object>
    __setstate__ = <built-in method __setstate__ of AttributeError object>
    __sizeof__ = <built-in method __sizeof__ of AttributeError object>
    __str__ = <method-wrapper '__str__' of AttributeError object>
    __subclasshook__ = <built-in method __subclasshook__ of type object>
    __suppress_context__ = False
    __traceback__ = <traceback object>
    args = ("'NoneType' object has no attribute 'glViewport'",)
    with_traceback = <built-in method with_traceback of AttributeError object>

The above is a description of an error in a Python program.  Here is
the original traceback:

Traceback (most recent call last):
  File "<string>", line 82, in resizeGL
AttributeError: 'NoneType' object has no attribute 'glViewport'

but if I hit Close then I get this after and a window behind in all black

AttributeError
Python 3.8.1: C:\Program Files\Krita (x64)\bin\krita.exe
Tue Dec  8 20:39:27 2020

A problem occurred in a Python script.  Here is the sequence of
function calls leading up to the error, in the order they occurred.

 C:\Program Files\Krita (x64)\<string> in paintGL(self=<__main__.MyViewport object>)

AttributeError: 'NoneType' object has no attribute 'glDrawArrays'
    __cause__ = None
    __class__ = <class 'AttributeError'>
    __context__ = None
    __delattr__ = <method-wrapper '__delattr__' of AttributeError object>
    __dict__ = {}
    __dir__ = <built-in method __dir__ of AttributeError object>
    __doc__ = 'Attribute not found.'
    __eq__ = <method-wrapper '__eq__' of AttributeError object>
    __format__ = <built-in method __format__ of AttributeError object>
    __ge__ = <method-wrapper '__ge__' of AttributeError object>
    __getattribute__ = <method-wrapper '__getattribute__' of AttributeError object>
    __gt__ = <method-wrapper '__gt__' of AttributeError object>
    __hash__ = <method-wrapper '__hash__' of AttributeError object>
    __init__ = <method-wrapper '__init__' of AttributeError object>
    __init_subclass__ = <built-in method __init_subclass__ of type object>
    __le__ = <method-wrapper '__le__' of AttributeError object>
    __lt__ = <method-wrapper '__lt__' of AttributeError object>
    __ne__ = <method-wrapper '__ne__' of AttributeError object>
    __new__ = <built-in method __new__ of type object>
    __reduce__ = <built-in method __reduce__ of AttributeError object>
    __reduce_ex__ = <built-in method __reduce_ex__ of AttributeError object>
    __repr__ = <method-wrapper '__repr__' of AttributeError object>
    __setattr__ = <method-wrapper '__setattr__' of AttributeError object>
    __setstate__ = <built-in method __setstate__ of AttributeError object>
    __sizeof__ = <built-in method __sizeof__ of AttributeError object>
    __str__ = <method-wrapper '__str__' of AttributeError object>
    __subclasshook__ = <built-in method __subclasshook__ of type object>
    __suppress_context__ = False
    __traceback__ = <traceback object>
    args = ("'NoneType' object has no attribute 'glDrawArrays'",)
    with_traceback = <built-in method with_traceback of AttributeError object>

The above is a description of an error in a Python program.  Here is
the original traceback:

Traceback (most recent call last):
  File "<string>", line 79, in paintGL
AttributeError: 'NoneType' object has no attribute 'glDrawArrays'

must say I love that glow effect :slight_smile:

Thank you for testing.

It looks like OpenGL 4.1 is to much to ask (released July 26, 2010)
For some weird reason only OpenGL 2.1 and OpenGL 4.1 Core, work inside of my Krita.
It looks like Qt / PyQt5 is missing some nuts & bolts, like all other versions :slight_smile:
Well Maybe OpenGL|ES 2.0 is supported, have to test tomorrow.

Shader is not my code, but just something easy & short to test out if everything works correctly :slight_smile:

original shader:

/AkiR

I am on Arch linux and it works for me, no error.

Hi

Tested on development computer, it works :slight_smile:

Here is the configuration

 Version: 4.4.2-beta1
 Languages: en_GB, en, fr, fr_FR, fr
 Hidpi: true

Qt

  Version (compiled): 5.12.9
  Version (loaded): 5.12.9

OS Information

  Build ABI: x86_64-little_endian-lp64
  Build CPU: x86_64
  CPU: x86_64
  Kernel Type: linux
  Kernel Version: 4.19.0-12-amd64
  Pretty Productname: Debian GNU/Linux 10 (buster)
  Product Type: debian
  Product Version: 10
  Desktop: KDE

OpenGL Info
 
  Vendor:  "NVIDIA Corporation" 
  Renderer:  "GeForce GTX 1060 3GB/PCIe/SSE2" 
  Version:  "4.6.0 NVIDIA 418.152.00" 
  Shading language:  "4.60 NVIDIA" 
  Requested format:  QSurfaceFormat(version 3.0, options QFlags<QSurfaceFormat::FormatOption>(DeprecatedFunctions), depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize 8, alphaBufferSize 8, stencilBufferSize 8, samples -1, swapBehavior QSurfaceFormat::DoubleBuffer, swapInterval 0, colorSpace QSurfaceFormat::DefaultColorSpace, profile  QSurfaceFormat::CompatibilityProfile) 
  Current format:    QSurfaceFormat(version 4.6, options QFlags<QSurfaceFormat::FormatOption>(DeprecatedFunctions), depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize 8, alphaBufferSize 8, stencilBufferSize 8, samples -1, swapBehavior QSurfaceFormat::DoubleBuffer, swapInterval 0, colorSpace QSurfaceFormat::DefaultColorSpace, profile  QSurfaceFormat::CompatibilityProfile) 
     Version: 4.6
     Supports deprecated functions true 
     is OpenGL ES: false 

QPA OpenGL Detection Info 
  supportsDesktopGL: true 
  supportsOpenGLES: true 
  isQtPreferOpenGLES: false 

Hardware Information

  GPU Acceleration: auto
  Memory: 32133 Mb
  Number of Cores: 8
  Swap Location: /tmp

Current Settings

  Current Swap Location: /tmp
  Current Swap Location writable: true
  Undo Enabled: true
  Undo Stack Limit: 250
  Use OpenGL: true
  Use OpenGL Texture Buffer: true
  Use AMD Vectorization Workaround: false
  Canvas State: OPENGL_SUCCESS
  Autosave Interval: 60
  Use Backup Files: true
  Number of Backups Kept: 2
  Backup File Suffix: ~
  Backup Location: Same Folder as the File
  Backup Location writable: false
  Use Win8 Pointer Input: false
  Use RightMiddleTabletButton Workaround: false
  Levels of Detail Enabled: false
  Use Zip64: true

The difference between my 2 computer is the graphic card

Working computer:

  Shading language:  "4.60 NVIDIA" 
  Requested format:  QSurfaceFormat(version 3.0, options QFlags<QSurfaceFormat::FormatOption>(DeprecatedFunctions), depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize 8, alphaBufferSize 8, stencilBufferSize 8, samples -1, swapBehavior QSurfaceFormat::DoubleBuffer, swapInterval 0, colorSpace QSurfaceFormat::DefaultColorSpace, profile  QSurfaceFormat::CompatibilityProfile) 
  Current format:    QSurfaceFormat(version 4.6, options QFlags<QSurfaceFormat::FormatOption>(DeprecatedFunctions), depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize 8, alphaBufferSize 8, stencilBufferSize 8, samples -1, swapBehavior QSurfaceFormat::DoubleBuffer, swapInterval 0, colorSpace QSurfaceFormat::DefaultColorSpace, profile  QSurfaceFormat::CompatibilityProfile) 
     Version: 4.6
     Supports deprecated functions true 
     is OpenGL ES: false 

Non working computer

  Shading language:  "1.30" 
  Requested format:  QSurfaceFormat(version 3.0, options QFlags<QSurfaceFormat::FormatOption>(DeprecatedFunctions), depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize 8, alphaBufferSize 8, stencilBufferSize 8, samples -1, swapBehavior QSurfaceFormat::DoubleBuffer, swapInterval 0, colorSpace QSurfaceFormat::DefaultColorSpace, profile  QSurfaceFormat::CompatibilityProfile) 
  Current format:    QSurfaceFormat(version 3.0, options QFlags<QSurfaceFormat::FormatOption>(DeprecatedFunctions), depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize 8, alphaBufferSize 8, stencilBufferSize 8, samples -1, swapBehavior QSurfaceFormat::DoubleBuffer, swapInterval 0, colorSpace QSurfaceFormat::DefaultColorSpace, profile  QSurfaceFormat::NoProfile) 
     Version: 3.0
     Supports deprecated functions true 
     is OpenGL ES: false 

So problem is not relative to OS or Python or Qt libraries, but with graphic card (or graphic card driver?) and supporter language version.

Grum999

I am using a Nvidia graphics card yes :\

Ah… :-/

Can you provide OpenGL from Help>Show system information ?
Maybe this can help to understand where the problem come from…

Grum999

the system report

Krita

 Version: 4.4.1
 Languages: en_US, en
 Hidpi: true

Qt

  Version (compiled): 5.12.9
  Version (loaded): 5.12.9

OS Information

  Build ABI: x86_64-little_endian-llp64
  Build CPU: x86_64
  CPU: x86_64
  Kernel Type: winnt
  Kernel Version: 10.0.18363
  Pretty Productname: Windows 10 (10.0)
  Product Type: windows
  Product Version: 10

OpenGL Info
 
  Vendor:  "Google Inc." 
  Renderer:  "ANGLE (NVIDIA GeForce GTX 650 Direct3D11 vs_5_0 ps_5_0)" 
  Version:  "OpenGL ES 3.0 (ANGLE 2.1.0.57ea533f79a7)" 
  Shading language:  "OpenGL ES GLSL ES 3.00 (ANGLE 2.1.0.57ea533f79a7)" 
  Requested format:  QSurfaceFormat(version 3.0, options QFlags<QSurfaceFormat::FormatOption>(DeprecatedFunctions), depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize 8, alphaBufferSize 8, stencilBufferSize 8, samples -1, swapBehavior QSurfaceFormat::DoubleBuffer, swapInterval 0, colorSpace QSurfaceFormat::DefaultColorSpace, profile  QSurfaceFormat::CompatibilityProfile) 
  Current format:    QSurfaceFormat(version 3.0, options QFlags<QSurfaceFormat::FormatOption>(), depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize 8, alphaBufferSize 8, stencilBufferSize 8, samples 0, swapBehavior QSurfaceFormat::DefaultSwapBehavior, swapInterval 0, colorSpace QSurfaceFormat::DefaultColorSpace, profile  QSurfaceFormat::NoProfile) 
     Version: 3.0
     Supports deprecated functions false 
     is OpenGL ES: true 

QPA OpenGL Detection Info 
  supportsDesktopGL: true 
  supportsAngleD3D11: true 
  isQtPreferAngle: true 

Hardware Information

  GPU Acceleration: auto
  Memory: 16332 Mb
  Number of Cores: 4
  Swap Location: C:/Users/EyeOd/AppData/Local/Temp

Current Settings

  Current Swap Location: C:/Users/EyeOd/AppData/Local/Temp
  Current Swap Location writable: true
  Undo Enabled: true
  Undo Stack Limit: 500
  Use OpenGL: true
  Use OpenGL Texture Buffer: true
  Use AMD Vectorization Workaround: false
  Canvas State: OPENGL_SUCCESS
  Autosave Interval: 1800
  Use Backup Files: true
  Number of Backups Kept: 1
  Backup File Suffix: ~
  Backup Location: C:/Users/EyeOd/AppData/Local/Temp
  Backup Location writable: true
  Use Win8 Pointer Input: false
  Use RightMiddleTabletButton Workaround: false
  Levels of Detail Enabled: false
  Use Zip64: false


Display Information
Number of screens: 1
	Screen: 0
		Name: \\.\DISPLAY1
		Depth: 32
		Scale: 1
		Resolution in pixels: 3840x2160
		Manufacturer: 
		Model: 
		Refresh Rate: 60

Current OpenGL example provided by @AkiR is for OpenGL 4.1 language version
It seems you NVidia card is compatible with version 3.0 only
Like me with my first computer

My second computer have a gc compatibvle with open gl 4.1 language and this why it’s working on it I think

But I’m not an expert, I’m discovering the stuff :slight_smile:

Testing provided script with a demo comptable for OpenGL 3.0 should work.
Need to find an example written in OpenGL 3.0 to confirm

Grum999

The problem here is probably ANGLE, if you set Krita to use ANGLE it doesn’t bind to your “normal” OpenGL driver, but the wrapper-library that translates OpenGL to Direct3D, and the highest it supports currently is ES 3.0 (which is not the same as “desktop” 3.0 btw., shaders are not source compatible which is a major PITA…)

Btw. on Ubuntu I had to install python3-pyqt5.qtopengl to make it work with my own builds, was a bit surprised it’s not in the main pyqt5 package…

For windows maybe, but on my Debian ?
:slight_smile:

The only difference (except hardware) between my 2 computer is version of krita
4.4.1 appimage on not working computer
4.4.2beta appimage on working computer

And I don’t think the both appimage contains different pyqt libraries ? :thinking:

I’ll try to find tonight an example for OpenGL 3.0 to test it on my 1st computer

Grum999

On my 1st computer, if I change profile.setVersion(4, 1) by profile.setVersion(2, 0) it doesn’t crash anymore
But I have no render (just a transparent window…)
Can’t really understand why…

Grum999

OpenGl 2.0 is really old, and had no support for shader programs.
(It’s from era of steam powered computers)

/AkiR

ah ok :sweat_smile:

tryied to set other values profile.setVersion(3, 0) for example, but I got an error message

ModuleNotFoundError: No module named 'PyQt5._QOpenGLFunctions_3_0'

Grum999

Ah yes my comment was only about EyeOdin’s OpenGL info…

Hm it says “Skylake GT2”, I thought it should support at least OpenGL 4.2 with Mesa even if it’s not the very latest MESA driver…

Well that’s exactly the error I got (just with _4_1 at the end) until I installed the python3-pyqt5.qtopengl package.

On my linuxmint computer I got

ModuleNotFoundError
Python 3.8.10: /usr/bin/python3
Mon Nov 29 18:55:15 2021
... ...
Traceback (most recent call last):
  File "<string>", line 60, in initializeGL
ModuleNotFoundError: No module named 'PyQt5._QOpenGLFunctions_4_1_Core'

and

AttributeError
Python 3.8.10: /usr/bin/python3
Mon Nov 29 18:57:36 2021
... ...
Traceback (most recent call last):
  File "<string>", line 82, in resizeGL
AttributeError: 'MyViewport' object has no attribute '_gl'

and

AttributeError
Python 3.8.10: /usr/bin/python3
Mon Nov 29 18:58:10 2021
... ...
Traceback (most recent call last):
  File "<string>", line 76, in paintGL
AttributeError: 'MyViewport' object has no attribute '_prog'

and two or more similar warnings.

My system info is

Krita

 Version: 4.4.8
 Languages: en_US, en, en_US, en
 Hidpi: true

Qt

  Version (compiled): 5.12.8
  Version (loaded): 5.12.8

OS Information

  Build ABI: x86_64-little_endian-lp64
  Build CPU: x86_64
  CPU: x86_64
  Kernel Type: linux
  Kernel Version: 5.4.0-90-generic
  Pretty Productname: Linux Mint 20.2
  Product Type: linuxmint
  Product Version: 20.2
  Desktop: X-Cinnamon

OpenGL Info
 
  Vendor:  "Intel" 
  Renderer:  "Mesa Intel(R) HD Graphics 500 (APL 2)" 
  Version:  "4.6 (Compatibility Profile) Mesa 21.0.3" 
  Shading language:  "4.60" 
  Requested format:  QSurfaceFormat(version 3.0, options QFlags<QSurfaceFormat::FormatOption>(DeprecatedFunctions), depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize 8, alphaBufferSize 8, stencilBufferSize 8, samples -1, swapBehavior QSurfaceFormat::DoubleBuffer, swapInterval 0, colorSpace QSurfaceFormat::DefaultColorSpace, profile  QSurfaceFormat::CompatibilityProfile) 
  Current format:    QSurfaceFormat(version 4.6, options QFlags<QSurfaceFormat::FormatOption>(DeprecatedFunctions), depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize 8, alphaBufferSize 8, stencilBufferSize 8, samples -1, swapBehavior QSurfaceFormat::DoubleBuffer, swapInterval 0, colorSpace QSurfaceFormat::DefaultColorSpace, profile  QSurfaceFormat::CompatibilityProfile) 
     Version: 4.6
     Supports deprecated functions true 
     is OpenGL ES: false 

QPA OpenGL Detection Info 
  supportsDesktopGL: true 
  supportsOpenGLES: true 
  isQtPreferOpenGLES: false 

Hardware Information

  GPU Acceleration: auto
  Memory: 3769 Mb
  Number of Cores: 4
  Swap Location: /tmp

Current Settings

  Current Swap Location: /tmp
  Current Swap Location writable: true
  Undo Enabled: true
  Undo Stack Limit: 30
  Use OpenGL: true
  Use OpenGL Texture Buffer: true
  Use AMD Vectorization Workaround: false
  Canvas State: OPENGL_SUCCESS
  Autosave Interval: 900
  Use Backup Files: true
  Number of Backups Kept: 1
  Backup File Suffix: ~
  Backup Location: Same Folder as the File
  Backup Location writable: false
  Use Win8 Pointer Input: false
  Use RightMiddleTabletButton Workaround: false
  Levels of Detail Enabled: false
  Use Zip64: false


Display Information
Number of screens: 1
	Screen: 0
		Name: eDP-1
		Depth: 24
		Scale: 1
		Resolution in pixels: 1366x768
		Manufacturer: BOE
		Model: 
		Refresh Rate: 60

Your code here and the one drawing Sierpinski triangles are pretty helpful to me btw :star_struck: