Search code examples
pythonpython-3.xopenglpyopengl

How do i use the function glDrawnPixels in pyopengl?


So i'm working on a voxel base engine and i'm currently changing from tkinter's canvas to PyOpenGl. I found the function glDrawnPixels who is very important for my engine. But here's the problem, i don't know OpenGL or PyOpenGl so much and my tentative sold with black pixel. So how do i do to have different color of pixel.

Here's a also my tentative :


import glfw
from OpenGL.GL import *
import numpy as np
import pyrr

buffer = bytearray(800 * 600 * 3)
display = (800,600)

if not glfw.init():
    raise Exception("glfw can not be initialized!")

def CreateWindow(title="Baguette game",width=1280,height=750):
    display = (width,height)
    buffer = bytearray(width * height * 3)
    window = glfw.create_window(width,height,title, None, None)
    glfw.set_window_pos(window,400,200)
    glfw.make_context_current(window)

    return window

def DrawTriangle(pointA=[-0.5, -0.5, 0.0],pointB=[0.5, -0.5,0.0],
                 pointC=[-0.5, 0, 0.0],color=[1.0,0,0]):
    vertices = [pointA[0], pointA[1], pointA[2],
                pointB[0], pointB[1], pointB[2],
                pointC[0], pointC[1], pointC[2]]

    colors = [color[0], color[1], color[2],
              color[0], color[1], color[2],
              color[0], color[1], color[2] ]
    
    v = np.array(vertices,dtype=np.float32)
    c = np.array(colors, dtype=np.float32)
    
    glEnableClientState(GL_VERTEX_ARRAY)
    glVertexPointer(3, GL_FLOAT,0,v)
    glEnableClientState(GL_COLOR_ARRAY)
    glColorPointer(3, GL_FLOAT,0,c)
    glDrawArrays(GL_TRIANGLES,0,3)
    
if __name__=="__main__":
    window = CreateWindow()
    initialPosition = (0,0,0)
    z=1
    while not glfw.window_should_close(window):
        glfw.poll_events()
        glClear(GL_COLOR_BUFFER_BIT)
        
        DrawTriangle([-0.5, -0.5, z],[0.5, -0.5,z],[-0.5, 0, z])
        glDrawPixels(display[1], display[0], GL_RGB, GL_UNSIGNED_BYTE, buffer)
        DrawTriangle([-0.5, 0.5, z],[0.5, 0.5,z],[-0.5, 1, z])
        
        glfw.swap_buffers(window)
    glfw.terminate()

In the center of the screen you can see a triangle cut by black pixels and above the complete triangle.


Solution

  • You can use OpenGL/PyOpenGL in a tkinter frame with pyopengltk. An example can be found here: tkinter_opengl_shader_ctypes_glm_meshes.py.
    glDrawPixels is deprecated, do not use it. Render primitives instead. See Primitive.

    Anyway you need to set the color date in the buffer (as suggested in a comment). e.g:

    buffer = bytearray(800 * 600 * 3)

    display = (1280, 750)
    buffer_data = [255, 128, 0] * (display[0] * display[1])
    buffer = (GLubyte * (display[0] * display[1] * 3))(*buffer_data)
    

    glDrawPixels(display[1], display[0], GL_RGB, GL_UNSIGNED_BYTE, buffer)

    glDrawPixels(display[0], display[1], GL_RGB, GL_UNSIGNED_BYTE, buffer)
    

    However, if you just want to set the clear color for the display, use glClearColor:

    glClearColor(1, 0.5, 0, 1)
    glClear(GL_COLOR_BUFFER_BIT)
    

    The color can be read back from the framebuffer with glReadPixels:

    color = glReadPixels(0, 0, display[0], display[1], GL_RGB, GL_UNSIGNED_BYTE, outputType='raw')