Skip to main content

No project description provided

Project description

OpenGL for Py++

pypp-opengl is a Py++ library for OpenGL

Examples

Drawing a triangle

The canonical OpenGL starting-point program of drawing a triangle.

from pypp_opengl import (
    GL,
    np,
    gl_gen_buffer,
    gl_gen_vertex_array,
    gl_shader_source,
    gl_get_shader_iv,
    gl_get_program_iv,
    gl_get_shader_info_log,
    gl_get_program_info_log,
    gl_delete_buffer,
    gl_delete_vertex_array,
    glad_load_gl,
)
from pypp_glfw import GLFWwindowPtr, glfw
from pypp_python import to_c_string, NULL, float32
from pypp_python.stl import ctypes

# Vertex shader source
vertex_shader_src: str = """
#version 330 core
layout(location = 0) in vec3 position;
layout(location = 1) in vec3 color;

out vec3 vertexColor;

void main()
{
    gl_Position = vec4(position, 1.0);
    vertexColor = color;
}
"""

# Fragment shader source
fragment_shader_src: str = """
#version 330 core
in vec3 vertexColor;
out vec4 FragColor;

void main()
{
    FragColor = vec4(vertexColor, 1.0);
}
"""


def compile_shader(source: str, shader_type: GL.GLenum) -> GL.GLuint:
    shader: GL.GLuint = GL.glCreateShader(shader_type)
    gl_shader_source(shader, source)
    GL.glCompileShader(shader)
    if not gl_get_shader_iv(shader, GL.GL_COMPILE_STATUS):
        raise RuntimeError(
            "Shader compilation failed: " + gl_get_shader_info_log(shader)
        )
    return shader


def create_shader_program() -> GL.GLuint:
    vertex_shader: GL.GLuint = compile_shader(vertex_shader_src, GL.GL_VERTEX_SHADER)
    fragment_shader: GL.GLuint = compile_shader(
        fragment_shader_src, GL.GL_FRAGMENT_SHADER
    )

    program: GL.GLuint = GL.glCreateProgram()
    GL.glAttachShader(program, vertex_shader)
    GL.glAttachShader(program, fragment_shader)
    GL.glLinkProgram(program)

    if not gl_get_program_iv(program, GL.GL_LINK_STATUS):
        raise RuntimeError(
            "Program linking failed: " + gl_get_program_info_log(program)
        )

    GL.glDeleteShader(vertex_shader)
    GL.glDeleteShader(fragment_shader)

    return program


def opengl_test():
    # Initialize GLFW
    if not glfw.init():
        raise Exception("Failed to initialize GLFW")

    glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4)
    glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 6)
    glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)

    # Create window
    window: GLFWwindowPtr = glfw.create_window(
        800, 600, to_c_string("PyOpenGL Triangle"), NULL, NULL
    )
    if not window:
        glfw.terminate()
        raise Exception("Failed to create GLFW window")

    glfw.make_context_current(window)

    if not glad_load_gl():
        raise Exception("Failed to initialize GLAD")

    # Vertex data (positions + colors)
    # fmt: off
    vertices: list[float32] = [
        -0.5, -0.5, 0.0, 
        1.0, 0.0, 0.0,  # bottom left (red)
        0.5, -0.5, 0.0,
        0.0, 1.0, 0.0,  # bottom right (green)
        0.0, 0.5, 0.0,
        0.0, 0.0, 1.0,  # top (blue)
    ]
    # fmt: on

    # Create VAO and VBO
    vao: GL.GLuint = gl_gen_vertex_array()
    vbo: GL.GLuint = gl_gen_buffer()

    GL.glBindVertexArray(vao)

    GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo)
    GL.glBufferData(
        GL.GL_ARRAY_BUFFER,
        len(vertices) * GL.sizeof(GL.GLfloat),
        np.array(vertices, np.float32),
        GL.GL_STATIC_DRAW,
    )

    # Position attribute
    GL.glVertexAttribPointer(
        0, 3, GL.GL_FLOAT, GL.GL_FALSE, 6 * GL.sizeof(GL.GLfloat), ctypes.c_void_p(0)
    )
    GL.glEnableVertexAttribArray(0)

    # Color attribute
    GL.glVertexAttribPointer(
        1,
        3,
        GL.GL_FLOAT,
        GL.GL_FALSE,
        6 * GL.sizeof(GL.GLfloat),
        ctypes.c_void_p(3 * GL.sizeof(GL.GLfloat)),
    )
    GL.glEnableVertexAttribArray(1)

    # Build shader program
    shader_program: GL.GLuint = create_shader_program()

    # Main render loop
    while not glfw.window_should_close(window):
        glfw.poll_events()

        GL.glClearColor(0.2, 0.3, 0.3, 1.0)
        GL.glClear(GL.GL_COLOR_BUFFER_BIT)

        GL.glUseProgram(shader_program)
        GL.glBindVertexArray(vao)
        GL.glDrawArrays(GL.GL_TRIANGLES, 0, 3)

        glfw.swap_buffers(window)

    # Cleanup
    gl_delete_vertex_array(vao)
    gl_delete_buffer(vbo)
    glfw.terminate()


if __name__ == "__main__":
    opengl_test()

API

The API is mainly defined by the PyOpenGL project (i.e. you use GL.someName, like with PyOpenGL). However, there are a few special functions that pypp-opengl has a separate API for, to make them more compatiable with Py++ (since Py++ is statically typed and does not use pointers). These special functions are:

gl_gen_buffer
gl_gen_buffers
gl_delete_buffer
gl_gen_vertex_array
gl_gen_vertex_arrays
gl_delete_vertex_array
gl_delete_vertex_arrays
gl_shader_source
gl_shader_sources
gl_get_shader_iv
gl_get_program_iv
gl_get_shader_info_log
gl_get_program_info_log

Supported OpenGL attributes and functions

Only the attributes and functions which are shown in the above examples are tested. However, its very likely that others will work also, and you will most easily find out by trying them in your code.

When you find an attribute or function which does not work, it would be really helpful if you submit a feature request with title support for <some_name>. Thanks in advance for if you do that.

Bug reports

Report bugs to the Issues tab on this github repo using the bug label.

Feature requests

Submit feature requests to the Issues tab on this github repo using the feature request label.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pypp_opengl-1.0.0a0.tar.gz (5.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pypp_opengl-1.0.0a0-py3-none-any.whl (8.5 kB view details)

Uploaded Python 3

File details

Details for the file pypp_opengl-1.0.0a0.tar.gz.

File metadata

  • Download URL: pypp_opengl-1.0.0a0.tar.gz
  • Upload date:
  • Size: 5.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for pypp_opengl-1.0.0a0.tar.gz
Algorithm Hash digest
SHA256 468d5dd41f5f8ba160e656c5f6b18a2b679b700980aa694586525653f865e21f
MD5 077819c8629379da3fb8b5869f6dd869
BLAKE2b-256 3b5d294e536e17c1522b715dd6fcaa585dc00dd17c44cb643345faf79af6a2e0

See more details on using hashes here.

File details

Details for the file pypp_opengl-1.0.0a0-py3-none-any.whl.

File metadata

  • Download URL: pypp_opengl-1.0.0a0-py3-none-any.whl
  • Upload date:
  • Size: 8.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for pypp_opengl-1.0.0a0-py3-none-any.whl
Algorithm Hash digest
SHA256 6e0d94b80ca466e44d24b6fbc2a9e15409e2a317074088502f1ea39f74d52fb1
MD5 b30b441921e72e86297962e4955a8244
BLAKE2b-256 d87b2253c3be232c147afda38f4b28ec48b0a94fe9e6c65b7b677075cec10ca7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page