| Line | Revision | Contents |
| 1 | 1 | """Panoramic image-cube Background node |
| 2 | """ |
|
| 3 | from OpenGLContext.scenegraph import imagetexture |
|
| 4 | 37 | from OpenGL.arrays import vbo |
| 5 | from OpenGLContext.arrays import array |
|
| 6 | 1 | from vrml import field, protofunctions, fieldtypes, node |
| 7 | from vrml.vrml97 import basenodes, nodetypes |
|
| 8 | ||
| 9 | from OpenGL.GL import * |
|
| 10 | from OpenGLContext.arrays import * |
|
| 11 | from math import pi |
|
| 12 | ||
| 13 | class URLField( fieldtypes.MFString ): |
|
| 14 | """Cube-background URL field which forwards to the corresponding ImageTexture node's url |
|
| 15 | """ |
|
| 16 | fieldType = "MFString" |
|
| 17 | def fset( self, client, value, notify=1 ): |
|
| 18 | value = super( URLField, self).fset( client, value, notify ) |
|
| 19 | imageObject = getattr(client, self.name[:-3]) |
|
| 20 | setattr( imageObject, 'url', value ) |
|
| 21 | return value |
|
| 22 | def fdel( self, client, notify=1 ): |
|
| 23 | value = super( URLField, self).fdel( client, notify ) |
|
| 24 | imageObject = getattr(client, self.name[:-3]) |
|
| 25 | delattr( imageObject, 'url') |
|
| 26 | return value |
|
| 27 | ||
| 28 | class _CubeBackground( object ): |
|
| 29 | right = field.newField('right', 'SFNode', default=imagetexture.ImageTexture) |
|
| 30 | top = field.newField('top', 'SFNode', default=imagetexture.ImageTexture) |
|
| 31 | back = field.newField('back', 'SFNode', default=imagetexture.ImageTexture) |
|
| 32 | left = field.newField('left', 'SFNode', default=imagetexture.ImageTexture) |
|
| 33 | front = field.newField('front', 'SFNode', default=imagetexture.ImageTexture) |
|
| 34 | bottom = field.newField('bottom', 'SFNode', default=imagetexture.ImageTexture) |
|
| 35 | |
|
| 36 | rightUrl = URLField( 'rightUrl') |
|
| 37 | topUrl = URLField( 'topUrl') |
|
| 38 | backUrl = URLField( 'backUrl') |
|
| 39 | leftUrl = URLField( 'leftUrl') |
|
| 40 | frontUrl = URLField( 'frontUrl') |
|
| 41 | bottomUrl = URLField( 'bottomUrl') |
|
| 42 | |
|
| 43 | bound = field.newField( 'bound', 'SFBool', 1, 0) |
|
| 44 | |
|
| 45 | def Render( self, mode, clear=1 ): |
|
| 46 | """Render the cube background |
|
| 47 | ||
| 48 | This renders those of our cube-faces which are |
|
| 49 | facing us, and which have a non-0 component-count. |
|
| 50 | ||
| 51 | After it's finished, it clears the depth-buffer |
|
| 52 | to make the geometry appear "behind" everything |
|
| 53 | else. |
|
| 54 | """ |
|
| 55 | if mode.passCount == 0: |
|
| 56 | 244 | glPushAttrib( GL_ALL_ATTRIB_BITS ) |
| 57 | 154 | glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS) |
| 58 | 1 | try: |
| 59 | glDisable( GL_LIGHTING ) |
|
| 60 | glDisable( GL_COLOR_MATERIAL ) |
|
| 61 | 37 | if not self.VBO: |
| 62 | self.compile( mode ) |
|
| 63 | 1 | if clear: |
| 64 | 116 | glClear( |
| 65 | GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT |
|
| 66 | ) |
|
| 67 | 244 | # we don't want to do anything with the depth buffer |
| 68 | # once we've cleared it... |
|
| 69 | glDepthMask( GL_FALSE ) |
|
| 70 | matrix = glGetDoublev( GL_MODELVIEW_MATRIX ) |
|
| 71 | if matrix is None: |
|
| 72 | # glGetDoublev can return None if uninitialised... |
|
| 73 | matrix = identity( 4, 'd') |
|
| 74 | forward = dot(matrix, [0,0,-1,0]) |
|
| 75 | self.VBO.bind() |
|
| 76 | glInterleavedArrays( GL_T2F_V3F, 0, self.VBO ) |
|
| 77 | 1 | try: |
| 78 | 244 | for offset,attr_name, normal, data in self.RENDER_DATA: |
| 79 | texture = getattr( self, attr_name ) |
|
| 80 | if dot(forward, normal) <=0 and texture.components: |
|
| 81 | # we are facing it, and it's loaded/non-null |
|
| 82 | texture.render(lit=0, mode=mode) |
|
| 83 | try: |
|
| 84 | glDrawArrays( GL_TRIANGLES, offset, 6 ) |
|
| 85 | finally: |
|
| 86 | texture.renderPost(mode=mode) |
|
| 87 | 1 | finally: |
| 88 | 244 | self.VBO.unbind() |
| 89 | 1 | finally: |
| 90 | 154 | glPopClientAttrib() |
| 91 | 244 | glPopAttrib() |
| 92 | 37 | |
| 93 | # TODO: should have one-per-context... |
|
| 94 | VBO = None |
|
| 95 | def compile( self, mode ): |
|
| 96 | """Compile a VBO with our various triangles to render""" |
|
| 97 | if self.VBO: |
|
| 98 | return self.VBO |
|
| 99 | def vertices( ): |
|
| 100 | for (offset,attr,norm,(a,b,c,d)) in self.RENDER_DATA: |
|
| 101 | yield a[1]+a[0] |
|
| 102 | yield b[1]+b[0] |
|
| 103 | yield c[1]+c[0] |
|
| 104 | yield a[1]+a[0] |
|
| 105 | yield c[1]+c[0] |
|
| 106 | yield d[1]+d[0] |
|
| 107 | vb = self.VBO = vbo.VBO(array(list(vertices()),'f')) |
|
| 108 | return vb |
|
| 109 | RENDER_DATA = [ |
|
| 110 | (0,'front',(0,0,1,0),[ |
|
| 111 | ((-1,-1,-1), (0,0)), |
|
| 112 | ((1,-1,-1), (1,0)), |
|
| 113 | ((1,1,-1), (1,1)), |
|
| 114 | ((-1,1,-1), (0,1)), |
|
| 115 | ]), |
|
| 116 | (6,'right',(-1,0,0,0),[ |
|
| 117 | ((1,-1,-1), (0,0)), |
|
| 118 | ((1,-1,1), (1,0)), |
|
| 119 | ((1,1,1), (1,1)), |
|
| 120 | ((1,1,-1), (0,1)), |
|
| 121 | ]), |
|
| 122 | (12,'back', (0,0,-1,0), [ |
|
| 123 | ((1,-1,1), (0,0)), |
|
| 124 | ((-1,-1,1), (1,0)), |
|
| 125 | ((-1,1,1), (1,1)), |
|
| 126 | ((1,1,1), (0,1)), |
|
| 127 | ]), |
|
| 128 | (18,'left',(1,0,0,0),[ |
|
| 129 | ((-1,-1,1), (0,0)), |
|
| 130 | ((-1,-1,-1), (1,0)), |
|
| 131 | ((-1,1,-1), (1,1)), |
|
| 132 | ((-1,1,1), (0,1)), |
|
| 133 | ]), |
|
| 134 | (24,'bottom',(0,1,0,0),[ |
|
| 135 | ((-1,-1,1), (0,0)), |
|
| 136 | ((1,-1,1), (1,0)), |
|
| 137 | ((1,-1,-1), (1,1)), |
|
| 138 | ((-1,-1,-1), (0,1)), |
|
| 139 | ]), |
|
| 140 | (30,'top',(0,-1,0,0),[ |
|
| 141 | ((-1,1,-1), (0,0)), |
|
| 142 | ((1,1,-1), (1,0)), |
|
| 143 | ((1,1,1), (1,1)), |
|
| 144 | ((-1,1,1), (0,1)), |
|
| 145 | ]), |
|
| 146 | ] |
|
| 147 | |
|
| 148 | 1 | |
| 149 | class CubeBackground( _CubeBackground, nodetypes.Background, nodetypes.Children, node.Node ): |
|
| 150 | """Image-cube Background node |
|
| 151 | ||
| 152 | The CubeBackground node implements 1/2 of the VRML97 |
|
| 153 | background node, particularly the image-cube |
|
| 154 | functionality represented by the rightUrl, topUrl, |
|
| 155 | backUrl, leftUrl, frontUrl, and bottomUrl fields. |
|
| 156 | ||
| 157 | Fields of note within the CubeBackground object: |
|
| 158 | ||
| 159 | back, front, left, right, top, bottom -- texture |
|
| 160 | objects applied to the geometry of the cube. |
|
| 161 | Any node which supports the texture API |
|
| 162 | should work for these attributes |
|
| 163 | |
|
| 164 | backUrl, frontUrl, leftUrl, rightUrl, topUrl, |
|
| 165 | bottomUrl -- texture urls (MFStrings) used to |
|
| 166 | load the images above |
|
| 167 | ||
| 168 | Note: the common practice in 3DSMax for creating |
|
| 169 | a cubic environment map produces useful |
|
| 170 | background images, but it is often necessary to |
|
| 171 | swap left and right images to work with the |
|
| 172 | VRML 97 system. |
|
| 173 | """ |
|
| 174 | |
Loggerhead 1.10 is a web-based interface for Bazaar branches