Bottom Page

Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
PyGlet Trouble Drawing Cube.
#1
I missing something. Just can't get that cube to draw.
Using numpy and modern Opengl. My graphic card support upto 4.6.
import pyglet
from pyglet.gl import *
from pyglet.graphics.vertexbuffer import create_buffer
from random import randrange
import numpy as np
import ctypes
import math

#           base on gl3n row major
def perspective(width, height, fov, near, far):
    array = np.array([0 for i in range(16)], dtype=float).reshape(4,4)
    mat = np.matrix(array)
    aspect = width/height
    top = near * math.tan(fov * (math.pi/360.0))
    bottom = -top
    right = top * aspect
    left = -right

    mat[0,0] = (2 * near) / (right - left)
    mat[0,2] = (right + left) / (right - left)
    mat[1,1] = (2 * near) / (top - bottom)
    mat[1,2] = (top + bottom) / (top - bottom)
    mat[2,2] = -(far + near) / (far - near)
    mat[2,3] = -(2 * far + near)  / (far - near)
    mat[3,2] = -1
    return mat

def normalized(array):
    if np.linalg.norm(array) != 0:
        return array / np.linalg.norm(array)
    return array

def matrix_idenity():
    return np.matrix(np.identity(4, dtype=float))

def look_at(eye, target, up):
    look_dir = normalized(target - eye)
    up_dir = normalized(up)
    right_dir = normalized(np.cross(look_dir, up_dir))
    perp_up_dir = np.cross(right_dir, look_dir)

    mat = matrix_idenity()
    mat[0] = np.append(right_dir, [-np.dot(eye, right_dir)])
    mat[1] = np.append(perp_up_dir, [-np.dot(eye, perp_up_dir)])
    mat[2] = np.append(-look_dir, [np.dot(eye, look_dir)])

    return mat

class Face:
    FRONT = 1     # counter clockwise
    BACK = 2
    LEFT = 4     # counter clockwise
    RIGHT = 8
    TOP = 16     # counter clockwise
    BOTTOM = 32
    ALL = 63

def create_cube(size, face=Face.ALL, element=True):
    array = np.array([
    size, size, size,       #0  + + +
    -size, -size, -size,    #1  - - -
    size, -size, -size,     #2  + - -
    size, size, -size,      #3  + + -
    -size, size, -size,     #4  - + -
    -size, size, size,      #5  - + +
    -size, -size, size,     #6  - - +
    size, -size, size       #7  + - +
    ], GLfloat)

    elements = np.array([], GLuint)
    if face & Face.BACK:
        elements = np.append(elements, [1,3,2,3,1,4])
    if face & Face.FRONT:
        elements = np.append(elements, [1,7,0,0,5,6])
    if face & Face.LEFT:
        elements = np.append(elements, [5,4,1,1,6,5])
    if face & Face.RIGHT:
        elements = np.append(elements, [0,2,3,2,0,7])
    if face & Face.TOP:
        elements = np.append(elements, [4,0,3,0,4,5])
    if face & Face.BOTTOM:
        elements = np.append(elements, [1,2,7,7,6,1])

    if element:
        return array, elements

    pylist = []
    for i in elements:
        n = i * 3
        pylist.extend(array[n:n + 3])

    return np.array(pylist, GLfloat)

class Shader:
    def __init__(self):
        self.program = GLuint(glCreateProgram())

        vbuffer = open('vshader.glsl', 'r')
        vshader = glCreateShader(GL_VERTEX_SHADER)
        vbuff = ctypes.create_string_buffer(vbuffer.read().encode())
        vtext = ctypes.cast(ctypes.pointer(ctypes.pointer(vbuff)), ctypes.POINTER(ctypes.POINTER(GLchar)))
        glShaderSource(vshader, 1, vtext, None)
        glCompileShader(vshader)

        success = GLint()
        infoLog = ctypes.create_string_buffer(512)
        glGetShaderiv(vshader, GL_COMPILE_STATUS, ctypes.byref(success))
        if not success:
            glGetShaderInfoLog(vshader, 512, None, infoLog)
            print("Error: Vertex Shader ", infoLog.value)

        fbuffer = open('fshader.glsl', 'r')
        fshader = glCreateShader(GL_FRAGMENT_SHADER)
        fbuff = ctypes.create_string_buffer(fbuffer.read().encode())
        ftext = ctypes.cast(ctypes.pointer(ctypes.pointer(fbuff)), ctypes.POINTER(ctypes.POINTER(GLchar)))
        glShaderSource(fshader, 1, ftext, None)
        glCompileShader(fshader)

        glGetShaderiv(fshader, GL_COMPILE_STATUS, ctypes.byref(success))
        if not success:
            glGetShaderInfoLog(fshader, 512, None, infoLog)
            print("Error: Fragment Shader ", infoLog.value)

        glAttachShader(self.program, vshader)
        glAttachShader(self.program, fshader)
        glLinkProgram(self.program)

        glGetProgramiv(self.program, GL_LINK_STATUS, ctypes.byref(success))
        if not success:
            glGetShaderInfoLog(fshader, 512, None, infoLog)
            print("Error: Program ", infoLog.value)

        # clean up
        glDeleteShader(vshader)
        glDeleteShader(fshader)
        vbuffer.close()
        fbuffer.close()

    def uniformMatrix4fv(self, key, count, transpose, value):
        buff = ctypes.create_string_buffer(key.encode())
        location = glGetUniformLocation(self.program, buff)
        nvalue = np.array(value, GLfloat) # .flatten()
        nref = nvalue.ctypes.data_as(ctypes.POINTER(ctypes.c_float))
        glUniformMatrix4fv(location, count, transpose, nref)

    def use(self):
        glUseProgram(self.program)

    def destroy(self):
        glDeleteProgram(self.program)

class Window(pyglet.window.Window):
    def __init__(self):
        pyglet.window.Window.__init__(self)
        self.context.config.alpha_size = 8
        self.context.config.buffer_size = 32
        self.context.config.sample_buffers = 1
        self.context.config.samples = 4

        glEnable(GL_DEPTH_TEST)
        glDepthFunc(GL_LESS)
        glClearColor(0.1, 0.0, 0.0, 1.0)
        glViewport(0, 0, self.width, self.height)
        print(self.width, self.height)

        self.model = matrix_idenity()
        eye = np.array([0,0,4], dtype=float)
        self.view = look_at(eye,
            eye + np.array([0,0,4], dtype=float),
            np.array([0,0,4], dtype=float))

        self.projection = perspective(self.width, self.height, 45.0, 1.0, 100.0)

        self.vertices = create_cube(0.4, element=False)
        self.vertices[2::3] -= 8
        print(self.vertices[:6])
        colors = []
        for i in range(6):
            color = [randrange(20, 256), randrange(20, 256), randrange(20, 256)]
            colors.extend(color + color + color + color + color + color)

        #self.cube = pyglet.graphics.vertex_list(36, ('v3f', verticies), ('c3B/static', colors))
        self.vao = GLuint()
        glGenVertexArrays(1, self.vao)
        glBindVertexArray(self.vao)

        self.vbo = create_buffer(self.vertices.nbytes, GL_ARRAY_BUFFER, GL_STATIC_DRAW)
        self.vbo.bind()
        self.vbo.set_data(self.vertices.ctypes.data)


        #glGenBuffers(1, pointer(self.VBO))
        #glBufferData(GL_ARRAY_BUFFER, self.vertices.nbytes, self.vertices, GL_STATIC_DRAW)
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, self.vertices.nbytes, 0);
        glEnableVertexAttribArray(0);
        glBindVertexArray(0);

        self.shader = Shader()

    def on_draw(self):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        self.shader.use()
        self.shader.uniformMatrix4fv('view', 1, GL_TRUE, self.view)
        self.shader.uniformMatrix4fv('model', 1, GL_TRUE, self.model)
        self.shader.uniformMatrix4fv('proj', 1, GL_TRUE, self.projection)

        glBindVertexArray(self.vao);
        glDrawArrays(GL_TRIANGLES, 0, len(self.vertices))
        glBindVertexArray(0)

if __name__ == '__main__':
    window = Window()
    pyglet.app.run()
Shaders
#version 330 core

layout (location = 0) in vec3 position;

uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;

void main()
{
	gl_Position = proj * view * model * vec4(position, 1.0f);
}
#version 330 core

void main()
{
	gl_FragColor = vec4(0.0, 0.0, 0.6, 1.0);
}
99 percent of computer problems exists between chair and keyboard.
Quote
#2
I have the cube drawing but the color is off. Color is to be on 1 side.
import pyglet
from pyglet.gl import *
from pyglet.graphics.vertexbuffer import create_buffer
from random import randrange
import numpy as np
import ctypes
import math
import os

#           base on gl3n row major
def perspective(width, height, fov, near, far):
    array = np.array([0 for i in range(16)], dtype=GLfloat).reshape(4,4)
    mat = np.matrix(array)
    aspect = width/height
    top = near * math.tan(fov * (math.pi/360.0))
    bottom = -top
    right = top * aspect
    left = -right

    mat[0,0] = (2 * near) / (right - left)
    mat[0,2] = (right + left) / (right - left)
    mat[1,1] = (2 * near) / (top - bottom)
    mat[1,2] = (top + bottom) / (top - bottom)
    mat[2,2] = -(far + near) / (far - near)
    mat[2,3] = -(2 * far + near)  / (far - near)
    mat[3,2] = -1
    return mat

def normalized(array):
    if np.linalg.norm(array) != 0:
        return array / np.linalg.norm(array)
    return array

def matrix_idenity():
    return np.matrix(np.identity(4, GLfloat))

def look_at(eye, target, up):
    look_dir = normalized(target - eye)
    up_dir = normalized(up)
    right_dir = normalized(np.cross(look_dir, up_dir))
    perp_up_dir = np.cross(right_dir, look_dir)

    mat = matrix_idenity()
    mat[0] = np.append(right_dir, [-np.dot(eye, right_dir)])
    mat[1] = np.append(perp_up_dir, [-np.dot(eye, perp_up_dir)])
    mat[2] = np.append(-look_dir, [np.dot(eye, look_dir)])

    return mat

def unit_vector(data):
    data = np.array(data, dtype=GLfloat, copy=True)
    if data.ndim == 1:
        data /= math.sqrt(np.dot(data, data))
        return data

def rotation(alpha, axis):
    cosa = math.cos(alpha)
    sina = math.sin(alpha)
    axis = unit_vector(axis)
    R = np.diag([cosa, cosa, cosa])
    R += np.outer(axis, axis) * (1.0 - cosa)
    axis *= sina
    R += np.array([[0.0, -axis[2], axis[1]],
                   [axis[2], 0.0, -axis[0]],
                   [-axis[1], axis[0], 0.0]], GLfloat)
    M = np.identity(4)
    M[:3, :3] = R
    return M

class Face:
    FRONT = 1     # counter clockwise
    BACK = 2
    LEFT = 4     # counter clockwise
    RIGHT = 8
    TOP = 16     # counter clockwise
    BOTTOM = 32
    ALL = 63

def create_cube(size, face=Face.ALL, element=True):
    array = np.array([
    size, size, size,       #0  + + + right   top      front
    -size, -size, -size,    #1  - - - left    bottom   back
    size, -size, -size,     #2  + - - right   bottom   back
    size, size, -size,      #3  + + - right   top      back
    -size, size, -size,     #4  - + - left    top      back
    -size, size, size,      #5  - + + left    top      front
    -size, -size, size,     #6  - - + left    bottom   front
    size, -size, size       #7  + - + right   bottom   front
    ], GLfloat)

    elements = np.array([], GLuint)
    if face & Face.BACK:
        elements = np.append(elements, [1,3,2,3,1,4])
    if face & Face.FRONT:
        elements = np.append(elements, [6,7,0,0,5,6])
    if face & Face.LEFT:
        elements = np.append(elements, [5,4,1,1,6,5])
    if face & Face.RIGHT:
        elements = np.append(elements, [0,2,3,2,0,7])
    if face & Face.TOP:
        elements = np.append(elements, [4,0,3,0,4,5])
    if face & Face.BOTTOM:
        elements = np.append(elements, [1,2,7,7,6,1])

    if element:
        return array, elements

    pylist = []
    for i in elements:
        n = i * 3
        pylist.extend(array[n:n + 3])

    return np.array(pylist, GLfloat)

class Shader:
    def __init__(self, vstring, fstring):
        self.program = GLuint(glCreateProgram())

        if not os.path.exists(vstring):
            print(vstring, "doesn't exists")
            return

        if not os.path.exists(fstring):
            print(fstring, "doesn't exists")
            return

        vbuffer = open(vstring, 'r')
        vshader = glCreateShader(GL_VERTEX_SHADER)
        vbuff = ctypes.create_string_buffer(vbuffer.read().encode())
        vtext = ctypes.cast(ctypes.pointer(ctypes.pointer(vbuff)), ctypes.POINTER(ctypes.POINTER(GLchar)))
        glShaderSource(vshader, 1, vtext, None)
        glCompileShader(vshader)

        success = GLint()
        infoLog = ctypes.create_string_buffer(512)
        glGetShaderiv(vshader, GL_COMPILE_STATUS, ctypes.byref(success))
        if not success:
            glGetShaderInfoLog(vshader, 512, None, infoLog)
            print("Error: Vertex Shader ", infoLog.value)

        fbuffer = open(fstring, 'r')
        fshader = glCreateShader(GL_FRAGMENT_SHADER)
        fbuff = ctypes.create_string_buffer(fbuffer.read().encode())
        ftext = ctypes.cast(ctypes.pointer(ctypes.pointer(fbuff)), ctypes.POINTER(ctypes.POINTER(GLchar)))
        glShaderSource(fshader, 1, ftext, None)
        glCompileShader(fshader)

        glGetShaderiv(fshader, GL_COMPILE_STATUS, ctypes.byref(success))
        if not success:
            glGetShaderInfoLog(fshader, 512, None, infoLog)
            print("Error: Fragment Shader ", infoLog.value)

        glAttachShader(self.program, vshader)
        glAttachShader(self.program, fshader)
        glLinkProgram(self.program)

        glGetProgramiv(self.program, GL_LINK_STATUS, ctypes.byref(success))
        if not success:
            glGetShaderInfoLog(fshader, 512, None, infoLog)
            print("Error: Program ", infoLog.value)

        # clean up
        glDeleteShader(vshader)
        glDeleteShader(fshader)
        vbuffer.close()
        fbuffer.close()

    def uniformMatrix4fv(self, key, count, transpose, value):
        buff = ctypes.create_string_buffer(key.encode())
        location = glGetUniformLocation(self.program, buff)
        nvalue = np.array(value, GLfloat) # .flatten()
        nref = nvalue.ctypes.data_as(ctypes.POINTER(ctypes.c_float))
        glUniformMatrix4fv(location, count, transpose, nref)

    def use(self):
        glUseProgram(self.program)

    def destroy(self):
        glDeleteProgram(self.program)

class Window(pyglet.window.Window):
    def __init__(self):
        pyglet.window.Window.__init__(self)
        self.context.config.alpha_size = 8
        self.context.config.buffer_size = 32
        self.context.config.sample_buffers = 1
        self.context.config.samples = 4

        glEnable(GL_DEPTH_TEST)
        glDepthFunc(GL_LESS)
        glClearColor(0.1, 0.0, 0.0, 1.0)
        glViewport(0, 0, self.width, self.height)

        self.model = matrix_idenity()
        self.view = look_at(
            np.array([4,3,3], dtype=GLfloat),
            np.array([0,0,0], dtype=GLfloat),
            np.array([0,1,0], dtype=GLfloat))

        self.projection = perspective(self.width, self.height, 45.0, 1.0, 100.0)
        self.mvp = self.projection * self.view * self.model

        self.vertices = create_cube(0.6, element=False)
        print("How many vertices.", len(self.vertices) / 3)
        color_choice = [[1.0,0.0,0.0], [0.0,1.0,0.0], [0.0,0.0,1.0],
            [1.0,0.0,1.0], [1.0,1.0,0.0], [0.0,0.5,1.0]]
        colors = []
        for i in range(6):
            color = color_choice[i]
            colors.extend(color + color + color + color + color + color)
        self.colors = np.array(colors, GLfloat)
        print("How many colors.", len(self.colors) / 3)

        self.vao = GLuint()
        glGenVertexArrays(1, self.vao)
        glBindVertexArray(self.vao)

        self.vbo = create_buffer(self.vertices.nbytes, GL_ARRAY_BUFFER, GL_STATIC_DRAW)
        self.vbo.set_data(self.vertices.ctypes.data)
        self.vbo.bind()

        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(0);

        self.color_vbo = create_buffer(self.colors.nbytes, GL_ARRAY_BUFFER, GL_STATIC_DRAW)
        self.color_vbo.set_data(self.colors.ctypes.data)
        self.color_vbo.bind()

        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(1);
        glBindVertexArray(0);

        self.tick = 0.0
        self.shader = Shader('vshader.glsl', 'fshader.glsl')
        pyglet.clock.schedule_interval(self.tick_update, 1.0 / 60.0)

    def tick_update(self, dt):
        self.tick += dt
        self.model = rotation(self.tick, np.array([0.1, 0.2, 0.3], GLfloat))
        self.mvp = self.projection * self.view * self.model

    def on_draw(self):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        self.shader.use()
        self.shader.uniformMatrix4fv('mvp', 1, GL_TRUE, self.mvp)

        glBindVertexArray(self.vao);
        glDrawArrays(GL_TRIANGLES, 0, len(self.vertices))
        glBindVertexArray(0)

    def clean_up(self):
        self.vbo.delete()
        self.color_vbo.delete()
        glDeleteVertexArrays(1, self.vao)

if __name__ == '__main__':
    window = Window()
    pyglet.app.run()
    window.clean_up()
shaders : edit replace duplicate fragment shader with vertex shader
#version 330 core

layout (location = 0) in vec3 position;
layout (location = 0) in vec3 color;

out vec3 fragColor;
uniform mat4 mvp;

void main()
{
	gl_Position = mvp * vec4(position, 1.0f);
    fragColor = color;
}
#version 330 core

in vec3 fragColor;
out vec3 color;

void main()
{
	color = fragColor;
}

Okay all figure out. Replace duplicate fragment shader above.
Color mistake was because I forgot to change layout location to 1.
layout (location = 0) in vec3 color;
to
layout (location = 1) in vec3 color;
nilamo likes this post
99 percent of computer problems exists between chair and keyboard.
Quote
#3
Thanks for sharing what the solution was :)

Also, thanks for sharing some code, I was recently wondering if python could use shaders easily, and it doesn't look that difficult at all.
Quote
#4
Shaders has nothing to do with python. Shaders are all opengl.
I was pulling my hair out. Dealing with pyglet and ctypes for the first time.
Doing this in D with opengl was simple. No ctypes.

Wish PyGlet wrap the cytpes. For I don't have to deal with them.
Need another option for opengl in python with no ctypes.
99 percent of computer problems exists between chair and keyboard.
Quote

Top Page

Possibly Related Threads...
Thread Author Replies Views Last Post
  problems with pyglet error catching jotes 1 228 Jul-24-2018, 11:34 AM
Last Post: Windspar
  New to Python, having some trouble ted_gress 5 458 Apr-30-2018, 09:37 PM
Last Post: nilamo

Forum Jump:


Users browsing this thread: 1 Guest(s)