[Yt-svn] yt-commit r1801 - in trunk/yt/extensions: . opengl_widgets
mturk at wrangler.dreamhost.com
mturk at wrangler.dreamhost.com
Sun Jul 25 20:24:30 PDT 2010
Author: mturk
Date: Sun Jul 25 20:24:29 2010
New Revision: 1801
URL: http://yt.enzotools.org/changeset/1801
Log:
Importing opengl_widgets directory from hg
Added:
trunk/yt/extensions/opengl_widgets/
trunk/yt/extensions/opengl_widgets/__init__.py
trunk/yt/extensions/opengl_widgets/calculateRay.vertex.glsl
trunk/yt/extensions/opengl_widgets/colormap.fragment.glsl
trunk/yt/extensions/opengl_widgets/framebuffer.vertex.glsl
trunk/yt/extensions/opengl_widgets/mip.fragment.glsl
trunk/yt/extensions/opengl_widgets/mip_viewer.py
trunk/yt/extensions/opengl_widgets/rendering_contexts.py
Modified:
trunk/yt/extensions/setup.py
Added: trunk/yt/extensions/opengl_widgets/__init__.py
==============================================================================
Added: trunk/yt/extensions/opengl_widgets/calculateRay.vertex.glsl
==============================================================================
--- (empty file)
+++ trunk/yt/extensions/opengl_widgets/calculateRay.vertex.glsl Sun Jul 25 20:24:29 2010
@@ -0,0 +1,63 @@
+/* Vertex shader to calculate the ray to cast through the volume data.
+ * The result is passed to the fragment shader using a varying.
+ *
+ * This file is part of Visvis.
+ * Copyright 2009 Almar Klein
+ */
+
+// the dimensions of the data, to determine stepsize
+uniform vec3 shape;
+
+// ratio to tune the number of steps
+uniform float stepRatio;
+
+// varyings to pass to fragment shader
+varying vec3 ray;
+
+void main()
+{
+
+ // First of all, set position.
+ // (We need to do this because this shader replaces the original shader.)
+ gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+
+ // Store texture coordinate (also a default thing).
+ gl_TexCoord[0].xyz = gl_MultiTexCoord0.xyz;
+
+ // Calculate the scaling of the modelview matrix so we can correct
+ // for axes.daspect and scale transforms of the wobject (in case
+ // of anisotropic data).
+ // We go from world coordinates to eye coordinates.
+ vec4 p0 = gl_ModelViewMatrix * vec4(0.0,0.0,0.0,1.0);
+ vec4 px = gl_ModelViewMatrix * vec4(1.0,0.0,0.0,1.0);
+ vec4 py = gl_ModelViewMatrix * vec4(0.0,1.0,0.0,1.0);
+ vec4 pz = gl_ModelViewMatrix * vec4(0.0,0.0,1.0,1.0);
+ float sx = length(p0.xyz - px.xyz);
+ float sy = length(p0.xyz - py.xyz);
+ float sz = length(p0.xyz - pz.xyz);
+
+ // Create a (diagonal) matrix to correct for the scaling
+ mat4 Ms = mat4(0.0);
+ Ms[0][0] = 1.0/(sx*sx);
+ Ms[1][1] = 1.0/(sy*sy);
+ Ms[2][2] = 1.0/(sz*sz);
+ Ms[3][3] = 1.0;
+
+ // Calculate ray direction. By correcting for the scaling, the ray is
+ // expressed in textute coordinates.
+ // We go from eye coordinates to world/texture coordinates.
+ vec4 p1 = vec4(0.0, 0.0, 0.0, 1.0) * gl_ModelViewProjectionMatrix * Ms;
+ vec4 p2 = vec4(0.0, 0.0, 1.0, 1.0) * gl_ModelViewProjectionMatrix * Ms;
+ ray = (p2.xyz/p2[3]) - (p1.xyz/p1[3]);
+
+ // Normalize ray to unit length.
+ ray = normalize(ray);
+
+ // Make the ray represent the length of a single voxel.
+ ray = ray / shape;
+ ray = ray * 0.58; // 1 over root of three = 0.577
+
+ // Scale ray to take smaller steps.
+ ray = ray / stepRatio;
+
+}
Added: trunk/yt/extensions/opengl_widgets/colormap.fragment.glsl
==============================================================================
--- (empty file)
+++ trunk/yt/extensions/opengl_widgets/colormap.fragment.glsl Sun Jul 25 20:24:29 2010
@@ -0,0 +1,12 @@
+uniform sampler1D colormap;
+uniform sampler2D buffer;
+void main()
+{
+ vec2 pos = vec3(gl_TexCoord[0]).xy;
+ vec4 value = texture2D(buffer, pos);
+ //gl_FragColor = texture1D(colormap, pos[1]);
+ gl_FragColor = texture1D(colormap, value[0]);
+ //gl_FragColor = vec4(1.0, 0.5, 0.3, 1.0);
+ //gl_FragColor = vec4(value[0], value[1], value[2], 1.0);
+ //gl_FragColor = vec4(pos[1], 0.0, 0.0, 1.0);
+}
Added: trunk/yt/extensions/opengl_widgets/framebuffer.vertex.glsl
==============================================================================
--- (empty file)
+++ trunk/yt/extensions/opengl_widgets/framebuffer.vertex.glsl Sun Jul 25 20:24:29 2010
@@ -0,0 +1,12 @@
+/* Vertex shader to calculate the ray to cast through the volume data.
+ * The result is passed to the fragment shader using a varying.
+ *
+ * This file is part of Visvis.
+ * Copyright 2009 Almar Klein
+ */
+
+void main()
+{
+ gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+ gl_TexCoord[0].xyz = gl_MultiTexCoord0.xyz;
+}
Added: trunk/yt/extensions/opengl_widgets/mip.fragment.glsl
==============================================================================
--- (empty file)
+++ trunk/yt/extensions/opengl_widgets/mip.fragment.glsl Sun Jul 25 20:24:29 2010
@@ -0,0 +1,135 @@
+/* Fragment shader for Maximum Intensity Projection (MIP) rendering.
+ * The ray is cast through the volume and we keep track of the
+ * smalest value. This is the fastest rendermethod available.
+ *
+ * This file is part of Visvis.
+ * Copyright 2009 Almar Klein
+ */
+
+// the 3D texture and colormap texture.
+uniform sampler3D texture;
+//uniform sampler1D colormap;
+
+// for window level and window width
+uniform vec2 scaleBias;
+
+// varying calculated by vertex shader
+varying vec3 ray;
+
+uniform vec3 shape;
+uniform vec3 position;
+
+float d2P(vec3 p, vec3 d, vec4 P)
+{
+ // calculate the distance of a point p to a plane P along direction d.
+ // plane P is defined as ax + by + cz = d
+ // line is defined as two points on that line
+
+ // calculate nominator and denominator
+ float nom = -( dot(P.rgb,p) - P.a );
+ float denom = dot(P.rgb,d);
+ // determine what to return
+ if (nom*denom<=0.0)
+ return 9999999.0; // if negative, or ON the plane, return ~inf
+ else
+ return nom / denom; // return normally
+}
+
+vec4 getRayAndSteps(vec3 edgeLoc)
+{
+ // Given the start pos, returns a corrected version of the ray
+ // and the number of steps combined in a vec4.
+
+ // Check for all six planes how many rays fit from the start point.
+ // Take the minimum value (not counting negative and 0).
+
+ float smallest = 9999999.0;
+ smallest = min(smallest, d2P(edgeLoc, ray, vec4(1.0, 0.0, 0.0, 0.0)));
+ smallest = min(smallest, d2P(edgeLoc, ray, vec4(0.0, 1.0, 0.0, 0.0)));
+ smallest = min(smallest, d2P(edgeLoc, ray, vec4(0.0, 0.0, 1.0, 0.0)));
+ smallest = min(smallest, d2P(edgeLoc, ray, vec4(1.0, 0.0, 0.0, 1.0)));
+ smallest = min(smallest, d2P(edgeLoc, ray, vec4(0.0, 1.0, 0.0, 1.0)));
+ smallest = min(smallest, d2P(edgeLoc, ray, vec4(0.0, 0.0, 1.0, 1.0)));
+
+ // round-off errors can cause the value to be very large.
+ // an n of 100.000 is pretty save
+ if (smallest > 9999.0)
+ smallest = 1.0;
+
+ // determine amount of steps and correct ray
+ vec4 result;
+ float n = ceil(smallest);
+ result.xyz = ray * (smallest/n);
+ result[3] = n;
+
+ // done
+ return result;
+}
+
+
+void main()
+{
+
+ // Get current pixel location.
+ vec3 edgeLoc = vec3(gl_TexCoord[0]);
+
+ // Get ray and steps.
+ vec4 tmp4 = getRayAndSteps(edgeLoc);
+ vec3 ray2 = tmp4.zyx;
+ int n = int(tmp4[3]);
+
+ // Init. Remember that we made sure that the total range of the data is
+ // mapped between 0 and 1 (also for signed data types).
+ //float maxval = texture3D(texture, edgeLoc + 1.0*ray2.xyz)[0];
+ float maxval = -1e30;
+
+ // Cast ray. For some reason the inner loop is not iterated the whole
+ // way for large datasets. Thus this ugly hack. If you know how to do
+ // it better, please let me know!
+ float val;
+ vec3 loc;
+ int i=0;
+ while (i<n)
+ {
+ for (i=i; i<n; i++)
+ {
+ // Calculate location.
+ loc = edgeLoc + float(i) * ray2;
+
+
+ // Sample value (avoid if statements).
+ val = texture3D( texture, loc )[0];
+ maxval = max(maxval, val);
+
+ // Sample value (with if statements).
+ //float val = texture3D( texture, loc )[0];
+ //if (val>maxval)
+ // maxval = val;
+ }
+ }
+
+ // Finaly, apply window-level window-width.
+ maxval = ( maxval + scaleBias[1] ) * scaleBias[0];
+ //maxval = (maxval - scale[0]) / (scale[1] - scale[0]);
+
+ //maxval = texture3D(texture, vec3(0.5, 0.5, 0.5))[0];
+
+ // Apply colormap.
+ //gl_FragColor = texture1D( colormap, maxval );
+ //gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ //gl_FragColor = vec4(val,val,val,1.0);
+ gl_FragColor = vec4(maxval,maxval,maxval,1.0);
+ //gl_FragColor = vec4(ray2[0],ray2[1],ray2[2],1.0);
+ //gl_FragColor = vec4(loc[0],loc[1],loc[2],1.0);
+ //gl_FragColor = vec4(edgeLoc[0],edgeLoc[1],edgeLoc[2],1.0);
+ //gl_FragColor = vec4(edgeLoc[0],edgeLoc[0],edgeLoc[0],1.0);
+ //gl_FragColor = vec4(ray[0],ray[1],ray[2],1.0);
+
+ //float mv = max(gl_FragData[1].r, maxval);
+ //if (mv < gl_FragData[1].r) discard;
+ //gl_FragData[0] = texture1D( colormap, mv);
+ //gl_FragData[1] = vec4(mv,mv,mv,mv);
+
+ // Apply a depth? No, does only really make sence for the iso renderer.
+ //gl_FragDepth = 2.0
+}
Added: trunk/yt/extensions/opengl_widgets/mip_viewer.py
==============================================================================
--- (empty file)
+++ trunk/yt/extensions/opengl_widgets/mip_viewer.py Sun Jul 25 20:24:29 2010
@@ -0,0 +1,450 @@
+"""
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: UCSD
+License:
+ Copyright (C) 2010 Matthew Turk All Rights Reserved.
+
+ This file is part of yt.
+
+ yt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+
+# A simple image viewer, soon to be useful for stereo images, using OpenGL.
+
+import sys, os
+import OpenGL.GL as GL
+import OpenGL.GLUT as GLUT
+import OpenGL.GLU as GLU
+import OpenGL.GL.shaders as shaders
+from OpenGL.arrays import vbo, ArrayDatatype
+import OpenGL.GL.ARB.framebuffer_object as GL_fbo
+import Image
+import glob
+import numpy as na
+import time
+
+from yt.extensions.opengl_image_viewer import ViewHandler3D, GenericGLUTScene
+from yt.extensions.image_writer import map_to_colors
+
+from rendering_contexts import render_fbo, create_fbo, identity_view, \
+ translate_view
+
+ESCAPE = '\033'
+
+_verts = ( (0,0,0), (1,0,0), (1,1,0), (0,1,0),
+ (0,0,0), (1,0,0), (1,0,1), (0,0,1),
+ (0,0,0), (0,0,1), (0,1,1), (0,1,0),
+ (0,1,0), (1,1,0), (1,1,1), (0,1,1),
+ (1,1,0), (1,0,0), (1,0,1), (1,1,1),
+ (0,0,1), (0,1,1), (1,1,1), (1,0,1) )
+
+_verts = ( (1,1,0), (0,1,0), (0,1,1), (1,1,1),
+ (1,0,1), (0,0,1), (0,0,0), (1,0,0),
+ (1,1,1), (0,1,1), (0,0,1), (1,0,1),
+ (1,0,0), (0,0,0), (0,1,0), (1,1,0),
+ (0,1,1), (0,1,0), (0,0,0), (0,0,1),
+ (1,1,0), (1,1,1), (1,0,1), (1,0,0) )
+
+_corner_list = [0,1,2,3, 4,5,6,7, 3,2,6,5, 0,4,7,1, 0,3,5,4, 1,7,6,2]
+_corner_vals = [ (0,0,0), (1,0,0), (1,1,0), (0,1,0),
+ (0,0,1), (0,1,1), (1,1,1), (1,0,1) ]
+
+_reversed = {2:0,1:1,0:2}
+
+def _compress(lr, s, i):
+
+ if lr == 0: return 0.5/s[_reversed[i]]
+ else: return -0.5/s[_reversed[i]]
+
+
+class MIPScene(GenericGLUTScene):
+ _display_mode = (GLUT.GLUT_RGBA | GLUT.GLUT_DOUBLE | GLUT.GLUT_DEPTH)
+ _title = "MIP"
+
+ gl_state = None
+
+ def _get_brick_vertices(self, offset):
+ for b in self.hv.bricks:
+ s = [ [-0.5, -0.5, -0.5],
+ [b.my_data[0].shape[i] - 1.5 for i in reversed(xrange(3))] ]
+ for corner in _corner_list:
+ for i, v in enumerate(_corner_vals[corner]):
+ yield s[v][i]
+
+ def _get_texture_vertices(self):
+ vs = [na.zeros(3, dtype='float32'),
+ na.ones(3, dtype='float32')]
+ #vs.reverse()
+ for b in self.hv.bricks:
+ shape = b.my_data[0].shape
+ for corner in _corner_list:
+ for i,v in enumerate(_corner_vals[corner]):
+ yield vs[v][i] + _compress(v, shape, i)
+
+ def _setup_bricks(self):
+ self._brick_textures = []
+ for g in self.hv.bricks:
+ self._upload_brick_textures(g)
+
+ def _upload_brick_textures(self, brick):
+ ix, iy, iz = brick.my_data[0].shape
+
+ GL.glActiveTexture(GL.GL_TEXTURE0)
+ id_field = GL.glGenTextures(1)
+ upload = brick.my_data[0].astype("float32")
+ #upload = (upload - -31.847) / ( -25.948 - -31.847 )
+ #mi, ma = -31.847, -25.948
+ #mi, ma = -27.2062, -20.9649
+ #upload = (upload - mi)/(ma - mi)
+ self.mi = min(upload.min(), self.mi)
+ self.ma = max(upload.max(), self.ma)
+ #upload = (255*(upload - -31.0) / (-25.0 - -31.0)).astype("uint8")
+
+ GL.glActiveTexture(GL.GL_TEXTURE0)
+ GL.glBindTexture(GL.GL_TEXTURE_3D, id_field)
+ GL.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1)
+ GL.glTexParameterf(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE)
+ GL.glTexParameterf(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE)
+ GL.glTexParameterf(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_WRAP_R, GL.GL_CLAMP_TO_EDGE)
+ GL.glTexParameterf(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR)
+ GL.glTexParameterf(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR)
+ GL.glTexImage3D(GL.GL_TEXTURE_3D, 0, GL.GL_LUMINANCE32F_ARB, iz, iy, ix, 0,
+ GL.GL_LUMINANCE, GL.GL_FLOAT, upload)
+
+ dds = ((brick.RightEdge - brick.LeftEdge) /
+ (na.array([ix,iy,iz], dtype='float32')-1))
+ self._brick_textures.append(
+ (id_field, (ix-1,iy-1,iz-1), dds, brick.LeftEdge - 0.5))
+
+ print "Uploaded", len(self._brick_textures)
+
+ def _setup_colormap(self):
+
+ buffer = na.mgrid[0.0:1.0:256j]
+ colors = map_to_colors(buffer, "algae")
+
+ GL.glActiveTexture(GL.GL_TEXTURE1)
+ id_cmap = GL.glGenTextures(1)
+
+ GL.glBindTexture(GL.GL_TEXTURE_1D, id_cmap)
+ GL.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1)
+ GL.glTexParameterf(GL.GL_TEXTURE_1D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE)
+ GL.glTexParameterf(GL.GL_TEXTURE_1D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR)
+ GL.glTexParameterf(GL.GL_TEXTURE_1D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR)
+ GL.glTexImage1D(GL.GL_TEXTURE_1D, 0, GL.GL_RGBA, 256, 0,
+ GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, colors)
+
+ self.gl_state["cmap_tex"] = id_cmap
+
+ def __init__(self, hv, offset = 0.5):
+ self.offset = offset
+ self.mi, self.ma = 1e30, -1e30
+ self.hv = hv
+ self.coord = 0.0
+ self.tfac = 10.0
+ self.rfac = 0.5
+ self.wireframe = False
+ self.glda = True
+ self._setup_keypress_handler()
+ self.gl_state = {}
+ GenericGLUTScene.__init__(self, 800, 800)
+
+ num = len(hv.bricks) * 6 * 4
+ self.v = na.fromiter(self._get_brick_vertices(offset),
+ dtype = 'float32', count = num * 3)
+ self.vertices = vbo.VBO(self.v)
+
+ self.t = na.fromiter(self._get_texture_vertices(),
+ dtype = 'float32', count = num * 3)
+ self.tvertices = vbo.VBO(self.t)
+
+ self.ng = len(hv.bricks)
+ self.position = na.zeros(3, dtype='float')
+ self.rotation = na.zeros(3, dtype='float') + 30
+ self.position[2] = -2 # Offset backwards a bit
+
+ self._setup_bricks()
+ create_fbo(self.gl_state)
+ self._setup_colormap()
+
+ def init_opengl(self, width, height):
+ # One-time GL setup
+
+ self.gl_state["width"] = width
+ self.gl_state["height"] = height
+
+ self.set_viewport()
+
+ # Now we compile our shaders
+ self.recompile()
+
+ def set_viewport(self):
+ if self.wireframe:
+ GL.glClearColor(1, 1, 1, 1)
+ else:
+ GL.glClearColor(0, 0, 0, 1)
+ GL.glColor3f(1, 0, 0)
+ GL.glEnable(GL.GL_DEPTH_TEST)
+
+ GL.glViewport(0, 0, self.gl_state["width"], self.gl_state["height"])
+ GL.glMatrixMode(GL.GL_PROJECTION)
+ GL.glLoadIdentity()
+ GLU.gluPerspective(60., self.gl_state["width"] / float(self.gl_state["height"]), 1e-3, 10.)
+ GL.glMatrixMode(GL.GL_MODELVIEW)
+
+ def recompile(self):
+ base = os.path.dirname(__file__) + "/"
+ self.program = compileProgram(
+ shaders.compileShader(
+ open(base+"calculateRay.vertex.glsl").read(),
+ GL.GL_VERTEX_SHADER),
+ shaders.compileShader(
+ open(base+"mip.fragment.glsl").read(),
+ GL.GL_FRAGMENT_SHADER))
+
+ def _set_simple_uniform(prog):
+ GL.glUseProgram(prog)
+ loc = GL.glGetUniformLocation(prog, 'buffer')
+ GL.glUniform1i(loc, 0)
+ loc = GL.glGetUniformLocation(prog, 'colormap')
+ GL.glUniform1i(loc, 1)
+ GL.glUseProgram(0)
+
+ self.fbo_program = compileProgram(
+ shaders.compileShader(
+ open(base+"framebuffer.vertex.glsl").read(),
+ GL.GL_VERTEX_SHADER),
+ shaders.compileShader(
+ open(base+"colormap.fragment.glsl").read(),
+ GL.GL_FRAGMENT_SHADER),
+ callback = _set_simple_uniform)
+
+ self.uniform_locations = dict( (
+ (v, GL.glGetUniformLocation(self.program, v)) for v in
+ ['texture','shape','scaleBias','stepRatio','position']
+ ) )
+ self.fbo_uniform_locations = dict( (
+ (v, GL.glGetUniformLocation(self.fbo_program, v)) for v in
+ ['colormap','buffer']
+ ) )
+
+ print self.uniform_locations, self.fbo_uniform_locations
+
+ @render_fbo
+ def _draw_boxes(self):
+ GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
+ GL.glDisable(GL.GL_DEPTH_TEST)
+ GL.glEnable(GL.GL_BLEND)
+ if self.wireframe:
+ GL.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE)
+ else:
+ GL.glBlendEquation(GL.GL_MAX)
+ GL.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL)
+ GL.glDisable(GL.GL_LINE_STIPPLE)
+ GL.glDisable(GL.GL_LINE_SMOOTH)
+ GL.glDisable(GL.GL_POINT_SMOOTH)
+ GL.glEnable(GL.GL_CULL_FACE)
+ #GL.glCullFace(GL.GL_FRONT)
+ GL.glCullFace(GL.GL_BACK)
+
+ GL.glLoadIdentity()
+ GL.glTranslatef(*self.position)
+ GL.glRotatef(self.rotation[0], 0, 0, 1)
+ GL.glRotatef(self.rotation[1], 0, 1, 0)
+ GL.glRotatef(self.rotation[2], 1, 0, 0)
+
+ GL.glColor3f(0.0, 0.0, 0.0)
+ GL.glUseProgram(self.program)
+ scalebias = ( 1.0/(self.ma - self.mi), -self.mi)
+ GL.glUniform1i(self.uniform_locations["texture"], 0)
+ GL.glUniform2f(self.uniform_locations["scaleBias"], scalebias[0], scalebias[1])
+ GL.glUniform1f(self.uniform_locations["stepRatio"], 1.0)
+ GL.glUniform3f(self.uniform_locations["position"], *self.position)
+
+ GL.glEnableClientState(GL.GL_VERTEX_ARRAY)
+ GL.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY)
+ #GL.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY_EXT)
+
+ GL.glColor3f(0.0, 0.0, 0.0)
+
+ GL.glActiveTexture(GL.GL_TEXTURE0)
+ GL.glEnable(GL.GL_TEXTURE_3D)
+
+ self.tvertices.bind()
+ GL.glTexCoordPointer(3, GL.GL_FLOAT, 0, self.tvertices)
+ self.vertices.bind()
+ GL.glVertexPointer(3, GL.GL_FLOAT, 0, self.vertices)
+
+ for i, texinfo in enumerate(self._brick_textures):
+ tex, shape, width, LE = texinfo
+ GL.glActiveTexture(GL.GL_TEXTURE0)
+ GL.glBindTexture(GL.GL_TEXTURE_3D, tex)
+ GL.glUniform1f(self.uniform_locations["stepRatio"], 0.1)
+ GL.glUniform3f(self.uniform_locations["shape"],
+ shape[2], shape[1], shape[0])
+ GL.glPushMatrix()
+ GL.glTranslate(LE[2], LE[1], LE[0])
+ GL.glScale(width[2], width[1], width[0])
+ if self.glda:
+ GL.glDrawArrays(GL.GL_QUADS, 24*i, 24)
+ else:
+ GL.glBegin(GL.GL_QUADS)
+ for fi in range(6):
+ for v in range(4):
+ #print -LE, width
+ off = i*72+fi*12+v*3
+ qv = self.v[off:off+3]
+ tv = self.t[off:off+3]
+ GL.glTexCoord3f(*tv)
+ GL.glVertex3f(*qv)
+ GL.glEnd()
+ GL.glPopMatrix()
+ GL.glDisableClientState(GL.GL_VERTEX_ARRAY)
+ GL.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY)
+ GL.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY_EXT)
+ self.vertices.unbind()
+ self.tvertices.unbind()
+ GL.glDisable(GL.GL_CULL_FACE)
+
+ def draw(self):
+
+ self._draw_boxes()
+
+ GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
+ GL.glUseProgram(self.fbo_program)
+
+ GL.glMatrixMode(GL.GL_MODELVIEW)
+ GL.glLoadIdentity()
+
+ GL.glMatrixMode(GL.GL_PROJECTION)
+ GL.glLoadIdentity()
+
+ GL.glActiveTexture(GL.GL_TEXTURE0)
+ GL.glEnable(GL.GL_TEXTURE_2D)
+ GL.glBindTexture(GL.GL_TEXTURE_2D, self.gl_state["fbo_tex"])
+
+ GL.glActiveTexture(GL.GL_TEXTURE1)
+ GL.glEnable(GL.GL_TEXTURE_1D)
+ GL.glBindTexture(GL.GL_TEXTURE_1D, self.gl_state["cmap_tex"])
+
+ GL.glUniform1i(self.fbo_uniform_locations["buffer"], 0)
+ GL.glUniform1i(self.fbo_uniform_locations["colormap"], 1)
+
+ GL.glColor3f(0.3, 0.5, 1.0)
+
+ GL.glBegin(GL.GL_QUADS)
+ GL.glTexCoord2i(0, 0)
+ GL.glVertex3i(-1, -1, -1)
+
+ GL.glTexCoord2i(0, 1)
+ GL.glVertex3i( 1, -1, -1)
+
+ GL.glTexCoord2i(1, 1)
+ GL.glVertex3i( 1, 1, -1)
+
+ GL.glTexCoord2i(1, 0)
+ GL.glVertex3i(-1, 1, -1)
+ GL.glEnd()
+
+ GL.glUseProgram(0)
+
+ GLUT.glutSwapBuffers()
+
+ def move_slice(self, value):
+ self.coord += value
+
+ def rotate(self, axis, value):
+ self.rotation[axis] += value/self.rfac
+
+ def reset_view(self):
+ print "RESETTING"
+ self.position = na.zeros(3, dtype='float')
+ self.rotation = na.zeros(3, dtype='float') + 30
+ self.position[2] = -2 # Offset backwards a bit
+
+ def translate(self, axis, value):
+ self.position[axis] += value/self.tfac
+
+ def toggle_wireframe(self):
+ self.wireframe = not self.wireframe
+ print "Wireframe:", self.wireframe
+
+ def toggle_glda(self):
+ self.glda = not self.glda
+ print "GLDA:", self.glda
+
+ def _setup_keypress_handler(self):
+ self.keypress_handler = ViewHandler3D(self)
+ self.keypress_handler.dispatch_table.update(dict(
+ y = (self.move_slice, ( 0.05,)),
+ h = (self.move_slice, (-0.05,)),
+ t = (self.toggle_wireframe, ()),
+ u = (self.toggle_glda, ()),
+ i = (self.recompile, ()),
+ o = (self.reset_view, ())
+ ))
+
+# We override the standard PyOpenGL one because otherwise we can't validate
+# multitexture shaders.
+def compileProgram(*my_shaders, **kwargs):
+ """Create a new program, attach my_shaders and validate
+
+ my_shaders -- arbitrary number of my_shaders to attach to the
+ generated program.
+
+ This convenience function is *not* standard OpenGL,
+ but it does wind up being fairly useful for demos
+ and the like. You may wish to copy it to your code
+ base to guard against PyOpenGL changes.
+
+ Usage:
+
+ shader = compileProgram(
+ compileShader( source, GL_VERTEX_SHADER ),
+ compileShader( source2, GL_FRAGMENT_SHADER ),
+ )
+ glUseProgram( shader )
+
+ Note:
+ If (and only if) validation of the linked program
+ *passes* then the passed-in shader objects will be
+ deleted from the GL.
+
+ returns GLuint shader program reference
+ raises RuntimeError when a link/validation failure occurs
+ """
+ program = GL.glCreateProgram()
+ for shader in my_shaders:
+ GL.glAttachShader(program, shader)
+ GL.glLinkProgram(program)
+ # Validation has to occur *after* linking
+ if 'callback' in kwargs: kwargs['callback'](program)
+ GL.glValidateProgram( program )
+ validation = GL.glGetProgramiv( program, GL.GL_VALIDATE_STATUS )
+ if validation == GL.GL_FALSE:
+ raise RuntimeError(
+ """Validation failure (%s): %s"""%(
+ validation,
+ GL.glGetProgramInfoLog( program ),
+ ))
+ link_status = GL.glGetProgramiv( program, GL.GL_LINK_STATUS )
+ if link_status == GL.GL_FALSE:
+ raise RuntimeError(
+ """Link failure (%s): %s"""%(
+ link_status,
+ GL.glGetProgramInfoLog( program ),
+ ))
+ for shader in my_shaders:
+ GL.glDeleteShader(shader)
+ return shaders.ShaderProgram( program )
Added: trunk/yt/extensions/opengl_widgets/rendering_contexts.py
==============================================================================
--- (empty file)
+++ trunk/yt/extensions/opengl_widgets/rendering_contexts.py Sun Jul 25 20:24:29 2010
@@ -0,0 +1,88 @@
+"""
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: UCSD
+License:
+ Copyright (C) 2010 Matthew Turk All Rights Reserved.
+
+ This file is part of yt.
+
+ yt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+
+import OpenGL.GL as GL
+import OpenGL.GLUT as GLUT
+import OpenGL.GLU as GLU
+import OpenGL.GL.shaders as shaders
+from OpenGL.arrays import vbo, ArrayDatatype
+import OpenGL.GL.ARB.framebuffer_object as GL_fbo
+from functools import wraps
+
+def render_fbo(func):
+ @wraps(func)
+ def fbo_renderer(self, fbo_id = "fbo_id", fbo_depth = "fbo_depth", **kwargs):
+ GL_fbo.glBindFramebuffer(GL_fbo.GL_FRAMEBUFFER,
+ self.gl_state[fbo_id])
+ GL_fbo.glBindRenderbuffer(GL_fbo.GL_RENDERBUFFER,
+ self.gl_state[fbo_depth])
+ self.set_viewport()
+ GL.glPushAttrib(GL.GL_VIEWPORT_BIT)
+ GL.glViewport(0, 0, self.gl_state["width"], self.gl_state["height"])
+ status = GL_fbo.glCheckFramebufferStatus(GL_fbo.GL_FRAMEBUFFER)
+ assert(status == GL_fbo.GL_FRAMEBUFFER_COMPLETE)
+
+ func(self, **kwargs)
+
+ GL.glPopAttrib(GL.GL_VIEWPORT_BIT)
+ GL_fbo.glBindFramebuffer(GL_fbo.GL_FRAMEBUFFER, 0)
+
+ return fbo_renderer
+
+def create_fbo(gl_state, fbo_id = "fbo_id", fbo_depth = "fbo_depth",
+ fbo_tex = "fbo_tex"):
+ GL.glActiveTexture(GL.GL_TEXTURE0)
+ id_fbo = GL.glGenTextures(1)
+ id_depth = GL_fbo.glGenRenderbuffers(1)
+ gl_state[fbo_tex] = id_fbo
+ gl_state[fbo_depth] = id_depth
+ gl_state[fbo_id] = GL_fbo.glGenFramebuffers(1)
+
+ GL.glBindTexture(GL.GL_TEXTURE_2D, id_fbo)
+ GL.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1)
+ GL.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE)
+ GL.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE)
+ GL.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST)
+ GL.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST)
+ GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA8,
+ gl_state["width"], gl_state["height"], 0,
+ GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, None)
+
+ GL_fbo.glBindFramebuffer(GL_fbo.GL_FRAMEBUFFER, gl_state[fbo_id])
+ GL_fbo.glFramebufferTexture2D(GL_fbo.GL_FRAMEBUFFER,
+ GL_fbo.GL_COLOR_ATTACHMENT0, GL.GL_TEXTURE_2D, gl_state[fbo_tex], 0)
+
+ GL_fbo.glBindRenderbuffer(GL_fbo.GL_RENDERBUFFER, id_depth)
+ GL_fbo.glRenderbufferStorage(GL_fbo.GL_RENDERBUFFER,
+ GL.GL_DEPTH_COMPONENT, gl_state["width"], gl_state["height"])
+ GL_fbo.glFramebufferRenderbuffer(
+ GL_fbo.GL_FRAMEBUFFER, GL_fbo.GL_DEPTH_ATTACHMENT,
+ GL_fbo.GL_RENDERBUFFER, id_depth)
+
+ GL_fbo.glBindFramebuffer(GL_fbo.GL_FRAMEBUFFER, 0)
+ GL_fbo.glBindRenderbuffer(GL_fbo.GL_RENDERBUFFER, 0)
+
+def identity_view(func):
+ pass
+
+def translate_view(func):
+ pass
Modified: trunk/yt/extensions/setup.py
==============================================================================
--- trunk/yt/extensions/setup.py (original)
+++ trunk/yt/extensions/setup.py Sun Jul 25 20:24:29 2010
@@ -11,4 +11,5 @@
config.add_subpackage("kdtree")
config.add_subpackage("image_panner")
config.add_subpackage("enzo_test")
+ config.add_subpackage("opengl_widgets")
return config
More information about the yt-svn
mailing list