Skip to content

Commit

Permalink
Merge pull request #137 from yt-project/matthewturk/issue135
Browse files Browse the repository at this point in the history
Multiple views in a single window
  • Loading branch information
chrishavlin authored Dec 9, 2024
2 parents 525c46f + f7f9de7 commit c1d36ab
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 70 deletions.
23 changes: 23 additions & 0 deletions examples/multiview_rendering.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import yt

import yt_idv
from yt_idv.scene_components.particles import ParticleRendering
from yt_idv.scene_data.particle_positions import ParticlePositions

ds = yt.load_sample("IsolatedGalaxy")

rc = yt_idv.render_context(height=800, width=800, gui=True)
sg = rc.add_scene(ds, "density", no_ghost=True)

sg.components[0].display_bounds = (0.0, 0.5, 0.0, 1.0)

dd = ds.all_data()
pos = ParticlePositions(data_source=dd)
pren = ParticleRendering(data=pos)

pren.display_bounds = (0.5, 1.0, 0.0, 1.0)

sg.data_objects.append(pos)
sg.components.append(pren)

rc.run()
5 changes: 5 additions & 0 deletions yt_idv/rendering_contexts/pyglet_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ def center_window(self):
self.set_position(0.5, 0.5)

def on_mouse_press(self, x, y, button, modifiers):
self._currently_clicked = True
self._do_update = True

def on_mouse_release(self, x, y, button, modifiers):
self._currently_clicked = False
self._do_update = True

def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
Expand Down
50 changes: 48 additions & 2 deletions yt_idv/scene_components/base_component.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,20 @@ class SceneComponent(traitlets.HasTraits):

display_name = traitlets.Unicode(allow_none=True)

# These attributes are
final_pass_vertex = ShaderTrait(allow_none=True).tag(shader_type="vertex")
final_pass_fragment = ShaderTrait(allow_none=True).tag(shader_type="fragment")
_final_pass = traitlets.Instance(ShaderProgram, allow_none=True)
_final_pass_invalid = True

# These attributes are just for colormap application
cmap_min = traitlets.CFloat(None, allow_none=True)
cmap_max = traitlets.CFloat(None, allow_none=True)
cmap_log = traitlets.Bool(True)
scale = traitlets.CFloat(1.0)

# This attribute determines whether or not this component is "active"
active = traitlets.Bool(True)

@traitlets.observe("display_bounds")
def _change_display_bounds(self, change):
# We need to update the framebuffer if the width or height has changed
Expand Down Expand Up @@ -261,6 +269,14 @@ def _colormap_vertex_default(self):
def _colormap_fragment_default(self):
return component_shaders[self.name][self.render_method]["second_fragment"]

@traitlets.default("final_pass_vertex")
def _final_pass_vertex_default(self):
return "passthrough"

@traitlets.default("final_pass_fragment")
def _final_pass_fragment_default(self):
return "display_border"

@traitlets.default("base_quad")
def _default_base_quad(self):
bq = SceneData(
Expand Down Expand Up @@ -302,6 +318,16 @@ def program2(self):
self._program2_invalid = False
return self._program2

@property
def final_pass(self):
if self._final_pass_invalid:
if self._final_pass is not None:
self._final_pass.delete_program()
self._final_pass = ShaderProgram(
self.final_pass_vertex, self.final_pass_fragment
)
return self._final_pass

def _set_iso_uniforms(self, p):
# these could be handled better by watching traits.
p._set_uniform("iso_num_layers", int(len(self.iso_layers)))
Expand All @@ -317,6 +343,10 @@ def _set_iso_uniforms(self, p):
def run_program(self, scene):
# Store this info, because we need to render into a framebuffer that is the
# right size.
if self.display_bounds != (0.0, 1.0, 0.0, 1.0):
draw_boundary = 0.002
else:
draw_boundary = 0.0
x0, y0, w, h = GL.glGetIntegerv(GL.GL_VIEWPORT)
GL.glViewport(0, 0, w, h)
if not self.visible:
Expand Down Expand Up @@ -351,6 +381,18 @@ def run_program(self, scene):
GL.glViewport(x0, y0, w, h)
GL.glDrawArrays(GL.GL_TRIANGLES, 0, 6)

if draw_boundary > 0.0:
with self.final_pass.enable() as p3:
p3._set_uniform("draw_boundary", float(draw_boundary))
if self.active:
boundary_color = np.array([0.0, 0.0, 1.0, 1.0], dtype="float32")
else:
boundary_color = np.array([0.5, 0.5, 0.5, 1.0], dtype="float32")
p3._set_uniform("boundary_color", boundary_color)
with self.base_quad.vertex_array.bind(p3):
GL.glViewport(x0, y0, w, h)
GL.glDrawArrays(GL.GL_TRIANGLES, 0, 6)

def draw(self, scene, program):
raise NotImplementedError

Expand Down Expand Up @@ -421,12 +463,16 @@ def _recompile_shader(self) -> bool:
"fragment_shader",
"colormap_vertex",
"colormap_fragment",
"final_pass_vertex",
"final_pass_fragment",
)
for shader_name in shaders:
s = getattr(self, shader_name, None)
if s:
s.delete_shader()
self._program1_invalid = self._program2_invalid = True
self._program1_invalid = self._program2_invalid = self._final_pass_invalid = (
True
)
return True

def _render_isolayer_inputs(self, imgui) -> bool:
Expand Down
13 changes: 13 additions & 0 deletions yt_idv/shaders/display_border.frag.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
in vec2 UV;

out vec4 color;

void main(){
color = texture(fb_tex, UV);
color.a = 1.0;
vec2 d = abs(UV - vec2(0.5));
if(0.5 - max(d.x, d.y) < draw_boundary) {
color = vec4(boundary_color);
}
gl_FragDepth = texture(db_tex, UV).r;
}
4 changes: 4 additions & 0 deletions yt_idv/shaders/known_uniforms.inc.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,7 @@ uniform int iso_num_layers;
uniform float iso_layers[32];
uniform float iso_layer_tol[32];
uniform float iso_alphas[32];

// draw outline control
uniform float draw_boundary;
uniform vec4 boundary_color;
Loading

0 comments on commit c1d36ab

Please sign in to comment.