Skip to content

Commit

Permalink
Starting creating image textures
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewturk committed Jul 5, 2024
1 parent 8eda1af commit 9a8497c
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 0 deletions.
60 changes: 60 additions & 0 deletions yt_idv/opengl_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,66 @@ def __iter__(self, target=0):
GL.glBindTexture(GL.GL_TEXTURE_3D, 0)


class ImageTexture(traitlets.HasTraits):
image_texture_name = traitlets.CInt(-1)
# This is, generally speaking, read-only. We don't want to write it from
# these objects. Instead, we will read it from a texture object that is
# similarly bound.
data = traittypes.Array(None, allow_none=True)
channels = GLValue("r32f")
min_filter = GLValue("linear")
mag_filter = GLValue("linear")
image_mode = GLValue("write only")

@traitlets.default("image_texture_name")
def _default_image_texture_name(self):
return GL.glGenTextures(1)

@contextmanager
def clear(self, target=0):
with self.bind(0, GL.GL_WRITE_ONLY):
GL.glClearTexImage(
self.image_texture_name, 0, self.channels, GL.GL_FLOAT, None
)
yield

@contextmanager
def bind(self, target=0, override_mode=None):
_ = GL.glActiveTexture(TEX_TARGETS[target])
mode = override_mode or self.image_mode
_ = GL.glBindImageTexture(
0, self.image_texture_name, 0, False, 0, mode, self.channels
)
yield
_ = GL.glActiveTexture(TEX_TARGETS[target])
GL.glBindImageTexture(0, 0, 0, False, 0, 0, 0)


# These require different semantics for creating the textures, as we still need
# to allocate storage for them on the texture unit.


class ImageTexture1D(ImageTexture):
boundary_x = TextureBoundary()
dims = 1
dims_enum = GLValue("texture 1d")


class ImageTexture2D(ImageTexture):
boundary_x = TextureBoundary()
boundary_y = TextureBoundary()
dims = 2
dims_enum = GLValue("texture 2d")


class ImageTexture3D(ImageTexture):
boundary_x = TextureBoundary()
boundary_y = TextureBoundary()
boundary_z = TextureBoundary()
dims = 3
dims_enum = GLValue("texture 3d")


def compute_box_geometry(left_edge, right_edge):
move = get_translate_matrix(*left_edge)
width = right_edge - left_edge
Expand Down
39 changes: 39 additions & 0 deletions yt_idv/scene_annotations/block_histogram.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import numpy as np
import traitlets
from OpenGL import GL

from yt_idv.scene_annotations.base_annotation import SceneAnnotation
from yt_idv.scene_data.block_collection import BlockCollection


class BlockHistogram(SceneAnnotation):
"""
A class that computes and displays a histogram of block data.
"""

name = "block_histogram"
data = traitlets.Instance(BlockCollection)
bins = traitlets.CInt(64)
min_val = traitlets.CFloat(0.0)
max_val = traitlets.CFloat(1.0)

def _set_compute_uniforms(self, scene, shader_program):
shader_program._set_uniform("min_val", self.min_val)
shader_program._set_uniform("max_val", self.max_val)
shader_program._set_uniform("bins", self.bins)

def compute(self, scene, program):
for _tex_ind, tex, bitmap_tex in self.data.viewpoint_iter(scene.camera):
# We now need to bind our textures. We don't care about positions.
with tex.bind(target=0):
with bitmap_tex.bind(target=1):
# This will need to be carefully chosen based on our
# architecture, I guess. That aspect of running compute
# shaders, CUDA, etc, is one of my absolute least favorite
# parts.
GL.glDispatchCompute(self.bins, 1, 1)

def draw(self, scene, program):
# This will probably need to have somewhere to draw the darn thing. So
# we'll need display coordinates, size, etc.
pass

0 comments on commit 9a8497c

Please sign in to comment.