When importing ShaderProgram, VertexShader, and FragmentShader, I cannot get them to display my GLMeshItem. I connect my shader to my GLMeshItem the way I see online in a very old forum: gl.shaders.Shaders.append(ShaderProgram('hilight', [ VertexShader(""" uniform mat4 u_mvp; attribute vec4 a_position; attribute vec3 a_normal; attribute vec4 a_color; varying vec4 v_color; varying vec3 normal; void main() { // compute here for use in fragment shader normal = normalize(gl_NormalMatrix * gl_Normal); v_color = a_color; gl_Position = u_mvp * a_position; } """), FragmentShader(""" #ifdef GL_ES precision mediump float; #endif varying vec4 v_color; varying vec3 normal; void main() { vec4 color = v_color; color.x = (normal.x + 1.0) * 0.5; color.y = (normal.y + 1.0) * 0.5; color.z = (normal.z + 1.0) * 0.5; gl_FragColor = color; } """) ])) Then calling self.current_plot = gl.GLMeshItem( meshdata=mesh_data, shader='hilight', # Set shader here smooth=True, drawFaces=True, computeNormals=True ) This fails but the same thing with shader='edgeHilight' (a built-in pyqtgraph shader) doesn't. Why? Even when 'hilight' is a carbon copy of 'edgeHilight', there is still no visual. I made sure it was added to the list of shaders by calling print("Shader program ID:", self.shader.program()) # Output 6 What's strange is that when I edit GLMeshItem's paint function like this: def paint(self): self.setupGLState() self.parseMeshData() if self.opts['drawFaces']: with self.shader(): # Add debug lines print("Position: " + str(glGetAttribLocation(self.shader().program(), 'a_position'))) print("Normal: " + str(glGetAttribLocation(self.shader().program(), 'a_normal'))) print("Color: " + str(glGetAttribLocation(self.shader().program(), 'a_color'))) # Rest of code... With shader='hilight': Position: 2 Normal: 0 Color: 1 but when shader='edgeHilight': Position: -1 Normal: -1 Color: -1 This is counterintuitive since the latter is the shader that works. Continue reading...