diff --git a/examples/variable_mesh_viewer.py b/examples/variable_mesh_viewer.py new file mode 100644 index 0000000..f433899 --- /dev/null +++ b/examples/variable_mesh_viewer.py @@ -0,0 +1,21 @@ +import yt + +import yt_idv +from yt_idv.scene_components.variable_mesh_display import VariableMeshDisplay +from yt_idv.scene_data.variable_mesh import VariableMeshContainer + +ds = yt.load_sample("IsolatedGalaxy") + +vm = ds.r[:, :, 0.5] + +rc = yt_idv.render_context(height=800, width=800, gui=True) +sg = rc.add_scene(ds, None) + +vmc = VariableMeshContainer(data_source=vm) +vmc.add_data("ones") +vmd = VariableMeshDisplay(data=vmc) + +sg.data_objects.append(vmc) +sg.components.append(vmd) + +rc.run() diff --git a/yt_idv/scene_components/variable_mesh_display.py b/yt_idv/scene_components/variable_mesh_display.py new file mode 100644 index 0000000..d52d77c --- /dev/null +++ b/yt_idv/scene_components/variable_mesh_display.py @@ -0,0 +1,24 @@ +import numpy as np +import traitlets +from OpenGL import GL + +from yt_idv.scene_components.base_component import SceneComponent +from yt_idv.scene_data.variable_mesh import VariableMeshContainer + + +class VariableMeshDisplay(SceneComponent): + """ + A class that renders variable mesh datasets. + """ + + name = "variable_mesh_display" + data = traitlets.Instance(VariableMeshContainer) + priority = 11 + + def draw(self, scene, program): + GL.glEnable(GL.GL_CULL_FACE) + GL.glCullFace(GL.GL_BACK) + GL.glDrawArraysInstanced(GL.GL_TRIANGLE_STRIP, 0, 4, self.data.size) + + def _set_uniforms(self, scene, program): + pass diff --git a/yt_idv/scene_data/variable_mesh.py b/yt_idv/scene_data/variable_mesh.py new file mode 100644 index 0000000..7a37e92 --- /dev/null +++ b/yt_idv/scene_data/variable_mesh.py @@ -0,0 +1,31 @@ +import numpy as np +import traitlets +from yt.data_objects.selection_objects.data_selection_objects import ( + YTSelectionContainer2D, +) + +from yt_idv.opengl_support import VertexArray, VertexAttribute +from yt_idv.scene_data.base_data import SceneData + + +class VariableMeshContainer(SceneData): + name = "variable_mesh" + data_source = traitlets.Instance(YTSelectionContainer2D) + + @traitlets.default("vertex_array") + def _default_vertex_array(self): + rv = VertexArray(name="vm_positions", each=1) + return rv + + def add_data(self, field): + if len(self.vertex_array.attributes) > 0: + # Has already been initialized, so we just update the data + self.vertex_array.attributes[-1].data = self.data_source[field].astype("f4") + return + for vfield in ("px", "py", "pdx", "pdy"): + f = self.data_source[vfield].in_units("unitary").astype("f4") + self.vertex_array.attributes.append(VertexAttribute(name=vfield, data=f)) + self.vertex_array.attributes.append( + VertexAttribute(name="field", data=self.data_source[field].astype("f4")) + ) + self.size = self.data_source["px"].size diff --git a/yt_idv/shaders/shaderlist.yaml b/yt_idv/shaders/shaderlist.yaml index 52f52eb..64a081f 100644 --- a/yt_idv/shaders/shaderlist.yaml +++ b/yt_idv/shaders/shaderlist.yaml @@ -133,6 +133,13 @@ shader_definitions: - one - zero blend_equation: func add + variable_mesh: + info: Sample a flat field value + source: variable_mesh.frag.glsl + depth_test: less + blend_func: + - one + - zero vertex: default: info: A first pass vertex shader that tranlates the location of vertices from @@ -160,6 +167,9 @@ shader_definitions: octree_position: info: Expect instanced rendering of octree nodes source: octree_position.vert.glsl + variable_mesh: + info: Billboard some variable mesh values + source: variable_mesh.vert.glsl geometry: grid_expand: info: Expand grid left and right edges into a set of triangles @@ -167,6 +177,9 @@ shader_definitions: particle_expand: info: Expand particles from points to triangulated quads source: particle_expand.geom.glsl + variable_mesh_expand: + info: Expand variable mesh points to quads + source: variable_mesh_expand.geom.glsl component_shaders: curve_rendering: default_value: default @@ -315,3 +328,12 @@ component_shaders: first_fragment: field_value second_vertex: passthrough second_fragment: apply_colormap + variable_mesh_display: + default_value: default + default: + description: Display variable mesh as quads + first_vertex: variable_mesh + first_geometry: variable_mesh_expand + first_fragment: variable_mesh + second_vertex: passthrough + second_fragment: apply_colormap diff --git a/yt_idv/shaders/variable_mesh.frag.glsl b/yt_idv/shaders/variable_mesh.frag.glsl new file mode 100644 index 0000000..3e4b03d --- /dev/null +++ b/yt_idv/shaders/variable_mesh.frag.glsl @@ -0,0 +1,8 @@ +flat in vec4 v_model; +flat in float field_value; +out vec4 output_color; + +void main() +{ + output_color = vec4(field_value); +} diff --git a/yt_idv/shaders/variable_mesh.vert.glsl b/yt_idv/shaders/variable_mesh.vert.glsl new file mode 100644 index 0000000..ec2434c --- /dev/null +++ b/yt_idv/shaders/variable_mesh.vert.glsl @@ -0,0 +1,15 @@ +in float px; +in float py; +in float pdx; +in float pdy; +in float field_value; + +flat out vec4 vv_model; +flat out float vv_field_value; + +void main() +{ + vv_model = vec4(px, py, pdx, pdy); + vv_field_value = field_value; + gl_Position = vec4(px, py, 0.0, 0.0); +} diff --git a/yt_idv/shaders/variable_mesh_expand.geom.glsl b/yt_idv/shaders/variable_mesh_expand.geom.glsl new file mode 100644 index 0000000..dda4464 --- /dev/null +++ b/yt_idv/shaders/variable_mesh_expand.geom.glsl @@ -0,0 +1,55 @@ +layout ( points ) in; +layout ( triangle_strip, max_vertices = 4 ) out; + +flat out vec4 v_model; +flat out float field_value; + +flat in vec4 vv_model[]; +flat in float vv_field_value[]; + + +void main() { + + // This is considerably simpler because we will just be doing things based + // on the positions in clip space + gl_Position = vec4( + vv_model[0].x - vv_model[0].z, + vv_model[0].y - vv_model[0].w, + 0.0, + 0.0 + ); + field_value = vv_field_value[0]; + v_model = vv_model[0]; + EmitVertex(); + + gl_Position = vec4( + vv_model[0].x - vv_model[0].z, + vv_model[0].y + vv_model[0].w, + 0.0, + 0.0 + ); + field_value = vv_field_value[0]; + v_model = vv_model[0]; + EmitVertex(); + + gl_Position = vec4( + vv_model[0].x + vv_model[0].z, + vv_model[0].y + vv_model[0].w, + 0.0, + 0.0 + ); + field_value = vv_field_value[0]; + v_model = vv_model[0]; + EmitVertex(); + + gl_Position = vec4( + vv_model[0].x + vv_model[0].z, + vv_model[0].y - vv_model[0].w, + 0.0, + 0.0 + ); + field_value = vv_field_value[0]; + v_model = vv_model[0]; + EmitVertex(); + +}