Source code for picogl.backend.modern.core.shader.mvp.helpers

"""
Set up model_matrix view projection (MVP) matrix for 3D rendering.

    This function constructs a combined projection and view matrix based on camera orbit angles,
    zoom level, and viewport aspect ratio. It simulates a camera orbiting around the origin
    and returns a 4x4 transformation matrix suitable for use in OpenGL shaders.


    :Example:

    .. code-block:: python

        mvp_parameters = setup_mvp(angle_x=0.5, angle_y=1.0, zoom=1.2, aspect=16/9)
"""

import numpy as np
from numpy import ndarray
from OpenGL.GL import glGetUniformLocation, glUniformMatrix4fv
from OpenGL.raw.GL._types import GL_TRUE
from pyglm import glm

from picogl.backend.legacy.core.camera.look_at import look_at
from picogl.backend.legacy.core.camera.perspective import perspective
from picogl.backend.modern.core.shader.rotation_matrix import create_rotation_matrix
from picogl.logger import Logger as log


[docs] def setup_mvp(angle_x: float, angle_y: float, zoom: float, aspect: float) -> glm.mat4: """ setup_mvp :param angle_x: Rotation angle around the X-axis (in radians). :type angle_x: float :param angle_y: Rotation angle around the Y-axis (in radians). :type angle_y: float :param zoom: Zoom factor controlling camera distance. :type zoom: float :param aspect: Aspect ratio of the viewport (width / height). :type aspect: float :return: Combined projection * view matrix. :rtype: glm.mat4 """ eye = glm.vec3(0, 0, 3 / zoom) center = glm.vec3(0, 0, 0) up = glm.vec3(0, 1, 0) # view and projection matrices view = glm.lookAt(eye, center, up) # Apply orbit rotation (same as Rx * Ry in numpy) view = glm.rotate(view, angle_x, glm.vec3(1, 0, 0)) view = glm.rotate(view, angle_y, glm.vec3(0, 1, 0)) projection = glm.perspective(glm.radians(45.0), aspect, 0.1, 100.0) return projection * view
[docs] def np_setup_mvp(shader, width, height, angle_x, angle_y, zoom) -> ndarray: """ setup_mvp :return: ndarray[Any, dtype[bool_]] """ target = np.array([0, 0, 0], dtype=np.float32) aspect = width / height if height > 0 else 1 proj = perspective(45.0, aspect, 0.1, 100.0) # Camera orbit rotation rotation = create_rotation_matrix(angle_x, angle_y) rotated_eye = (rotation @ np.array([0, 0, 3 / zoom, 1.0], dtype=np.float32))[:3] rotated_up = (rotation @ np.array([0, 1, 0, 0], dtype=np.float32))[:3] view = look_at(rotated_eye, target, rotated_up) mvp = proj @ view mvp_loc = glGetUniformLocation(shader, "mvp_matrix") if mvp_loc == -1: log.error("❌ Failed to find uniform location for 'mvp_matrix'") else: glUniformMatrix4fv(mvp_loc, 1, GL_TRUE, mvp.astype(np.float32)) return mvp