Search code examples
pythonopenglglsltranslationpyopengl

Translating an object not working as intended


When I try to create a cube that can be moved around using the z-axis using a translation matrix, half of the cube doesn't render and when I try to change the z-value, the FOV seems to increase.

Is it because of the translation matrix, or is there some other error going on here, and how would I fix it?

Full code:

import glfw
import numpy
import pyrr
from OpenGL.GL import *
from OpenGL.GL.shaders import *
width, height = 500, 500

rot_x_var = 0
rot_y_var = 0
z = 0

def draw():
    global shader, rot_x_var, rot_y_var, z
    cube = [-0.5, -0.5,  0.5, 1.0, 0.0, 0.0, #red
            0.5, -0.5,  0.5, 0.0, 1.0, 0.0, #green
            0.5,  0.5,  0.5, 0.0, 0.0, 1.0, #blue
            -0.5,  0.5,  0.5, 1.0, 1.0, 0.0, #yellow
            -0.5, -0.5, -0.5, 0.0, 1.0, 1.0, #cyan
            0.5, -0.5, -0.5, 1.0, 0.0, 1.0, #pink
            0.5,  0.5, -0.5, 0.0, 0.5, 0.0, #half-green
            -0.5,  0.5, -0.5, 1.0, 1.0, 1.0] #white

    cube = numpy.array(cube, dtype = numpy.float32)

    indices = [0, 3, 2, 2, 0, 1,
               1, 2, 6, 6, 1, 5,
               5, 1, 0, 0, 4, 5,
               5, 4, 7, 7, 6, 5,
               2, 6, 7, 7, 3, 2,
               0, 4, 7, 7, 3, 0]


    indices = numpy.array(indices, dtype= numpy.uint32)

    vertex_shader_ = """
        #version 140
        in vec4 position;
        in vec3 color;
        uniform mat4 transform;
        out vec4 out_color;
        uniform ivec2 dim;
        uniform mat4 z;
        void main(){

            gl_Position = transform*vec4(position.xyz, dim.x/dim.y)*z;
            out_color = vec4(color.rgb, 0.9);

        };

    """

    fragment_shader_ = """
        #version 140
        in vec4 out_color;

        void main(){

            gl_FragColor = out_color;
        };

    """

    shader = compileProgram(compileShader(vertex_shader_, GL_VERTEX_SHADER),
                            compileShader(fragment_shader_, GL_FRAGMENT_SHADER))
    glUseProgram(shader)
    glLinkProgram(shader)
    dim = glGetUniformLocation(shader, "dim")
    glUniform2i(dim, int(width), int(height))

    z_matrix = glGetUniformLocation(shader, "z")
    z_trans = numpy.array([0, 0, z, 0])
    glUniformMatrix4fv(z_matrix, 1, GL_FALSE, z_trans)

    VBO = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, VBO)
    glBufferData(GL_ARRAY_BUFFER, cube.nbytes, cube, GL_STATIC_DRAW)

    EBO = glGenBuffers(1)
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.nbytes, indices, GL_STATIC_DRAW)


    position = glGetAttribLocation(shader, "position")
    glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 24, ctypes.c_void_p(0))
    glEnableVertexAttribArray(position)
    color = glGetAttribLocation(shader, "color")
    glVertexAttribPointer(color, 3, GL_FLOAT, GL_FALSE, 24, ctypes.c_void_p(12))
    glEnableVertexAttribArray(color)


    glEnable(GL_DEPTH_TEST)
    rot_x = pyrr.Matrix44.from_x_rotation(rot_x_var)
    rot_y = pyrr.Matrix44.from_y_rotation(rot_y_var)
    transformLoc = glGetUniformLocation(shader, "transform")
    glUniformMatrix4fv(transformLoc, 1, GL_FALSE, rot_x * rot_y)






def Screen():
    glClearColor(0, 0, 0, 1)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
    glDrawElements(GL_TRIANGLES, 64, GL_UNSIGNED_INT, None)
    draw()
    glViewport(0, 0, width, height)


def main():
    global width, height, rot_x_var, rot_y_var, z
    if not glfw.init():
        return
    window = glfw.create_window(500, 500, "PyOpenGL GLFW", None, None)
    if not window:
        glfw.terminate()
        return

    glfw.make_context_current(window)

    while not glfw.window_should_close(window):
        glfw.poll_events()
        if glfw.get_key(window, glfw.KEY_DOWN) == glfw.PRESS:
            rot_x_var += 0.01
        if glfw.get_key(window, glfw.KEY_UP) == glfw.PRESS:
            rot_x_var -= 0.01
        if glfw.get_key(window, glfw.KEY_RIGHT) == glfw.PRESS:
            rot_y_var += 0.01
        if glfw.get_key(window, glfw.KEY_LEFT) == glfw.PRESS:
            rot_y_var -= 0.01
        if glfw.get_key(window, glfw.KEY_E) == glfw.PRESS:
            z += 0.1
        if glfw.get_key(window, glfw.KEY_Q) == glfw.PRESS:
            z -= 0.1
        Screen()
        width, height = glfw.get_window_size(window)



        glfw.swap_buffers(window)

    glfw.terminate()


if __name__ == '__main__':
    main()

Update: I have tweaked around with the code, and now the cube is not being shown, instead of the cube being deformed. Is there any way to fix this?


Solution

  • I had found the error. It was with this line:

    z_trans = numpy.array([0, 0, z, 0])
    

    I had to convert it to a matrix instead of an array.

    z_trans = pyrr.Matrix44([1, 0, 0, 0,
                             0, 1, 0, 0,
                             0, 0, 1, z,
                             0, 0, 0, 1])