Search code examples
pythonpython-3.xopenglpyqt5pyopengl

Error while Transforming the Object using PyOpenGL with PyQt5


I am trying to transform the object using vector shader. But glUniformMatrixfv raises error while execution.

vertex_shader = shaders.compileShader(
                """
                #version 330
                layout (location = 0) in vec3 pos;
                layout (location = 1) in vec3 color;
                uniform mat4 movement;
                out vec4 f_color;
                void main() 
                { 
                    gl_Position = movement * vec4(pos, 1.0);
                    f_color = vec4(color, 1.0);
                }
                """
                , GL_VERTEX_SHADER)


fragment_shader = shaders.compileShader(
                """
                #version 330
                in vec4 f_color;
                out vec4 gl_FragColor;
                void main() 
                {
                    gl_FragColor = f_color;
                }
                """
                , GL_FRAGMENT_SHADER
                )

Program code to use these shaders is:

def draw_object(self):
    self.vao = glGenVertexArrays(1)
    glBindVertexArray(self.vao)

    self.vbo_buffer = np.array([
        -0.4, 0.2, 0.0, 0.0, 1.0, 0.0,
        -0.8, -0.2, 0.0, 1.0, 1.0, 0.0,
        0.0, -0.2, 0.0, 0.0, 1.0, 1.0,
        0.2, -0.4, 0.0, 1.0, 0.0, 0.0,
        0.8, -0.4, 0.0, 0.0, 0.0, 1.0,
        0.8, 0.4, 0.0, 0.0, 1.0, 1.0,
        0.2, -0.4, 0.0, 1.0, 0.0, 0.0,
        0.8, 0.4, 0.0, 0.0, 0.0, 1.0,
        0.2, 0.4, 0.0, 0.0, 1.0, 0.0
    ], dtype=np.float32)

    self.vbo = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
    glBufferData(GL_ARRAY_BUFFER, self.vbo_buffer.nbytes, self.vbo_buffer, GL_DYNAMIC_DRAW)

    self.vertex_position = glGetAttribLocation(self.shader, bytestr('pos'))
    glVertexAttribPointer(self.vertex_position, 3, GL_FLOAT, GL_FALSE, 24, None)
    glEnableVertexAttribArray(self.vertex_position)

    self.vertex_color = glGetAttribLocation(self.shader, bytestr('color'))
    glVertexAttribPointer(self.vertex_color, 3, GL_FLOAT, GL_FALSE, 24, ctypes.c_void_p(12))
    glEnableVertexAttribArray(self.vertex_color)

    self.movement = glGetUniformLocation(self.shader, 'movement')
    glUniformMatrix4fv(self.movement, 1, GL_FALSE, glm.value_ptr(self.svp_matrix))

    glBindBuffer(GL_ARRAY_BUFFER, 0)
    glBindVertexArray(0)


def calculate_mvp(self):
    self.projection_matrix = glm.perspective(glm.radians(self.fieldOfView), self.glWinWidth / self.glWinHeight, 
                             self.nearPlane, self.farPlane)
    self.view_matrix = glm.rotate(glm.mat4(1.0), float(self.xRot), glm.vec3(1.0, 0.0, 0.0)) * \
                       glm.rotate(glm.mat4(1.0), float(self.yRot), glm.vec3(0.0, 1.0, 0.0)) * \
                       glm.rotate(glm.mat4(1.0), float(self.zRot), glm.vec3(0.0, 0.0, 1.0)) * \
                       glm.translate(glm.mat4(1.0), glm.vec3(self.xTranslate, self.yTranslate, self.zTranslate))
    self.scale_matrix = glm.scale(glm.mat4(1.0), glm.vec3(self.scale_factor))

    self.svp_matrix = self.projection_matrix * self.view_matrix * self.scale_matrix


def paintGL(self):
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glUseProgram(self.shader)
    try:
        glBindVertexArray(self.vao)
        glDrawArrays(GL_TRIANGLES, 0, 9) 
    finally:
        glBindVertexArray(0)
        glUseProgram(0)
        glFlush()

Error I am getting is:

File "C:\Program Files\Python37\lib\site-packages\OpenGL\platform\baseplatform.py", line 415, in __call__

return self( *args, **named )

File "src\errorchecker.pyx", line 58, in OpenGL_accelerate.errorchecker._ErrorChecker.glCheckError OpenGL.error.GLError: GLError(

   err = 1282,
   description = b'invalid operation',
   baseOperation = glUniformMatrix4fv,
   pyArgs = (
           0,
           1,
           GL_FALSE,
           <OpenGL.GLU.tess.LP_c_float object at 0x0000013A37B1B4C8>,
   ),
   cArgs = (
           0,
           1,
           GL_FALSE,
           <OpenGL.GLU.tess.LP_c_float object at 0x0000013A37B1B4C8>,
   ),
   cArguments = (
           0,
           1,
           GL_FALSE,
           <OpenGL.GLU.tess.LP_c_float object at 0x0000013A37B1B4C8>,
   )

)

If you know how to fix this please share below. Thanks


Solution

  • glUniformMatrix4fv sets the value of a uniform variable in the default uniform block currently installed program.
    The means the program has to be installed by glUseProgram, before the variable can be set. If there is no current program object, then an GL_INVALID_OPERATION error is generated.

    Install the program before glUniformMatrix4fv:

    self.movement = glGetUniformLocation(self.shader, 'movement')
    
    glUseProgram(self.shader)
    glUniformMatrix4fv(self.movement, 1, GL_FALSE, glm.value_ptr(self.svp_matrix))