Source code for picogl.texture.gltexture

"""
This module provides functionality for managing 2D OpenGL textures.

It includes a class for creating, binding, uploading data, setting parameters, generating mipmaps, and deleting
2D textures in OpenGL. This class ensures efficient management of texture resources in graphics applications.

Example Usage:
==============

  >> spec = TextureSpec(width=width, height=height)
  >> tex = Texture2D(spec, data)
  >> driver = GLTextureDriver()
  >> driver.create(tex)
  >> driver.bind(tex)
  >> driver.set_parameters()
  >> driver.upload(tex)
  >> driver.generate_mipmap()
  >> return tex.handle

"""

from contextlib import contextmanager
from enum import IntEnum
from typing import Any

from OpenGL.raw.GL.VERSION.GL_1_0 import (
    GL_TEXTURE_2D,
    GL_TEXTURE_MAG_FILTER,
    GL_TEXTURE_MIN_FILTER,
    GL_TEXTURE_WRAP_S,
    GL_TEXTURE_WRAP_T,
)
from OpenGL.raw.GL.VERSION.GL_1_2 import GL_TEXTURE_3D
from OpenGL.raw.GL.VERSION.GL_1_3 import GL_ACTIVE_TEXTURE, GL_TEXTURE0
from OpenGL.raw.GL.VERSION.GL_4_5 import GL_TEXTURE_BINDING_2D

from picogl.backend.gl.state.param import GLParam
from picogl.backend.gl.state.query import GLStateQuery
from picogl.backend.gl.wrappers import gl_active_texture, gl_bind_texture


[docs] class GLTexture(IntEnum): """gl Texture Mode"""
[docs] TEXTURE_2D = GL_TEXTURE_2D
[docs] TEXTURE_3D = GL_TEXTURE_3D
[docs] TEXTURE_BINDING_2D = GL_TEXTURE_BINDING_2D
[docs] TEXTURE_MIN_FILTER = GL_TEXTURE_MIN_FILTER
[docs] TEXTURE_MAG_FILTER = GL_TEXTURE_MAG_FILTER
[docs] TEXTURE_WRAP_S = GL_TEXTURE_WRAP_S
[docs] TEXTURE_WRAP_T = GL_TEXTURE_WRAP_T
[docs] TEXTURE0 = GL_TEXTURE0
[docs] ACTIVE_TEXTURE = GL_ACTIVE_TEXTURE
@classmethod
[docs] def choices(cls): return [m.value for m in cls]
@staticmethod
[docs] def set_active(unit=TEXTURE0): gl_active_texture(unit)
@staticmethod
[docs] def bind(target: int, texture: int): gl_bind_texture(texture, target)
@staticmethod @contextmanager
[docs] def enabled_texture2d(): """Texture 2D Enabled""" was_enabled = GLTexture.get_enabled_tex2d() try: if not was_enabled: GLTexture.enable_tex2d() yield finally: if not was_enabled: GLTexture.disable_tex2d()
@staticmethod
[docs] def disable_tex2d(): from picogl.backend.gl.driver.capability import GLCapabilityDriver GLCapabilityDriver.disable(GL_TEXTURE_2D)
@staticmethod
[docs] def enable_tex2d(): from picogl.backend.gl.driver.capability import GLCapabilityDriver GLCapabilityDriver.enable(GL_TEXTURE_2D)
@staticmethod
[docs] def get_enabled_tex2d(self) -> Any: from picogl.backend.gl.driver.capability import GLCapabilityDriver return GLCapabilityDriver.is_enabled(GL_TEXTURE_2D)
@staticmethod @contextmanager
[docs] def bound_texture(texture_id: int, unit: int = GL_TEXTURE0): """ Bind a texture to a specific unit, restoring previous state. """ state = GLStateQuery() # 1. Save currently active unit (GL_TEXTUREi enum) prev_active = state.get(GLParam.ACTIVE_TEXTURE) try: # 2. Switch to requested unit GLTexture.set_active(unit) # 3. NOW read binding for this unit prev_binding = state.get(GLParam.TEXTURE_BINDING_2D) # 4. Bind new texture GLTexture.bind(GL_TEXTURE_2D, texture_id or 0) yield finally: # Restore binding on the SAME unit GLTexture.bind(GL_TEXTURE_2D, prev_binding) # Restore previously active unit GLTexture.set_active(prev_active)