python - OpenGL 4.2+ and shader_image_load_store for 3D textures not working? -


i trying figure out why i'm not able write 3d textures using (now built-in) shader_image_load_store extension.

i created 2 simple examples (in python make easier): 1 write 2d texture, works, , 1 write 3d texture not work

the (working) 2d version following:

#! /usr/bin/env python  pyqt4 import qtgui, qtcore pyqt4.qtopengl import * opengl.gl import * opengl.glu import * import sys  itexsize = 256   _vsclearsource =  """     #version 440 compatibility     void main() {         gl_position = ftransform();         gl_frontcolor = gl_color;     }     """       _fsclearsource =   """ #version 440 compatibility uniform int         iprimitivecount; uniform int         isliceindex;  layout(size4x32, binding=0) coherent uniform   image2d volcolorvolume; const int imaxtexsize = 255;    void main() {     ivec2 ivecvolumecoordinate = ivec2(gl_fragcoord.x, gl_fragcoord.y ); //, isliceindex);      vec4 vecvolumevalue =  vec4(0,1,0,1); // vec4(         float(islabindex)/float(iprimitivecount)); //,0.0,0.0,0.0);     imagestore(volcolorvolume, ivecvolumecoordinate, vecvolumevalue);                      gl_fragdata[0] = vec4(1,0,1,1); }         """      _fsfillsource =   """ #version 440 compatibility uniform int         iprimitivecount; uniform int         isliceindex;  layout(size4x32, binding=0) coherent uniform   image2d volcolorvolume; const int imaxtexsize = 255;    void main() {     ivec2 ivecvolumecoordinate = ivec2(gl_fragcoord.x, gl_fragcoord.y );      vec4 vecvolumevalue =  vec4( float(gl_fragcoord.x)  / float(imaxtexsize)  , float(gl_fragcoord.y)  / float(imaxtexsize)  , 0 ,  1  );     imagestore(volcolorvolume, ivecvolumecoordinate, vecvolumevalue);                      gl_fragdata[0] = vec4(1,0,1,1); }     """           class viewer3dwidget(qglwidget):      def __init__(self, parent):         qglwidget.__init__(self, parent)          self.uwidth = 0         self.uheight = 0          self.texcolortexture = none         self.fborendering    = none         self.texcolorvolume = none          self.vecbackgroundcolor = (1.,1.,1.)          self.vecdrawbuffers = [ gl_color_attachment0 , gl_color_attachment1 , gl_color_attachment2, gl_color_attachment3, gl_color_attachment4, gl_color_attachment5 ]           self.fsurfacesspacing = 1.0         self.fsurfacestransparency = 1.0           def initializegl(self):         self.shashaderfill = qglshaderprogram(self.context())         self.shashaderfill.addshaderfromsourcecode(qglshader.vertex, _vsclearsource)         self.shashaderfill.addshaderfromsourcecode(qglshader.fragment, _fsfillsource)            self.shashaderfill.link()                self.shashaderclear = qglshaderprogram(self.context())         self.shashaderclear.addshaderfromsourcecode(qglshader.vertex, _vsclearsource)         self.shashaderclear.addshaderfromsourcecode(qglshader.fragment, _fsclearsource)            self.shashaderclear.link()                   glclearcolor(1.0, 1.0, 1.0, 1.0)         glcleardepth(1.0)       def initrendertargets(self):         global itexsize         if (self.texcolortexture none):             self.texcolortexture = glgentextures( 1 )         if (self.fborendering  none):             self.fborendering = glgenframebuffers(1)                         glbindtexture( gl_texture_rectangle, self.texcolortexture )         gltexparameteri(gl_texture_rectangle, gl_texture_wrap_s, gl_clamp)         gltexparameteri(gl_texture_rectangle, gl_texture_wrap_t, gl_clamp)         gltexparameteri(gl_texture_rectangle, gl_texture_min_filter, gl_nearest)         gltexparameteri(gl_texture_rectangle, gl_texture_mag_filter, gl_nearest)         glteximage2d(gl_texture_rectangle, 0, gl_rgba32f, itexsize, itexsize, 0, gl_rgba, gl_float, none)           glbindtexture(gl_texture_rectangle, 0);          glbindframebuffer(gl_framebuffer, self.fborendering)         glframebuffertexture2d(gl_framebuffer, gl_color_attachment0, gl_texture_rectangle,  self.texcolortexture, 0)         glbindframebuffer(gl_framebuffer, 0)           def deleterendertargets(self):         if (self.fboaccumulation  not  none):             gldeleteframebuffers(1,self.fborendering)                       self.fboaccumulation = none         if (self.texcolortexture not none):             gldeletetextures( self.texcolortexture )             self.texcolortexture = none       def initcolorvolume(self):         if (self.texcolorvolume none):             self.texcolorvolume = glgentextures( 1 )           glbindtexture( gl_texture_2d, self.texcolorvolume )         gltexparameteri(gl_texture_2d, gl_texture_wrap_s, gl_clamp)         gltexparameteri(gl_texture_2d, gl_texture_wrap_t, gl_clamp)         #gltexparameteri(gl_texture_3d, gl_texture_wrap_r, gl_clamp)         gltexparameteri(gl_texture_2d, gl_texture_min_filter, gl_nearest)         gltexparameteri(gl_texture_2d, gl_texture_mag_filter, gl_nearest)         glteximage2d(gl_texture_2d, 0, gl_rgba32f, itexsize, itexsize, 0, gl_rgba, gl_float, none);           glbindtexture(gl_texture_2d, 0);            def fillvolume(self, bclear):         global itexsize          shashader = self.shashaderclear         if(not bclear):             shashader = self.shashaderfill          if (not self.fborendering):             self.initrendertargets()           if (not self.texcolorvolume):             self.initcolorvolume()          glmatrixmode( gl_projection )         glloadidentity()          glmatrixmode( gl_modelview );         glloadidentity();                        glbindimagetexture(0,self.texcolorvolume,0,gl_false,0,gl_read_write,gl_rgba32f);          glbindframebuffer(gl_framebuffer, self.fborendering);         gldrawbuffers(1, self.vecdrawbuffers);          glclearcolor(0, 0, 0, 0);         glclear(gl_color_buffer_bit);                      shashader.bind()          shashader.setuniformvalue("iprimitivecount", itexsize)           shashader.setuniformvalue("volcolorvolume", 0)           in range(itexsize):               shashader.setuniformvalue("isliceindex", i)                  glbegin(gl_quads);             glvertex2f(-1.0, -1.0);              glvertex2f(1.0, -1.0);             glvertex2f(1.0, 1.0);             glvertex2f(-1.0, 1.0);             glend();               #sync             glmemorybarrier(gl_all_barrier_bits);           glbindimagetexture(0,0,0,gl_false,0,gl_read_write,gl_rgba32f);         shashader.release()          glbindframebuffer(gl_framebuffer, 0);       def paintgl(self):         if  (self.uwidth 0):             return                    if (not self.fborendering):             self.initrendertargets()              self.initcolorvolume()          glmatrixmode( gl_projection )         glloadidentity()          glmatrixmode( gl_modelview );         glloadidentity();          glclear(gl_color_buffer_bit | gl_depth_buffer_bit)           self.fillvolume(true)         #draw volume         self.fillvolume(false)          #slice volume         self.displaytexture()            glflush()         def displaytexture(self):   #essentially not useable here         glmatrixmode( gl_projection )         glloadidentity()         glmatrixmode( gl_modelview );         glloadidentity();         gldisable(gl_blend)         gldisable(gl_depth_test);           gldisable(gl_lighting)          glclear(gl_color_buffer_bit | gl_depth_buffer_bit)         glcolor(1.0, 1.0,1.0)            glenable(gl_texture_2d);          glbindtexture( gl_texture_2d, self.texcolorvolume )          glbegin(gl_quads);         gltexcoord2f(0,0) #,0.5)         glvertex2f(-1.0, -1.0);          gltexcoord2f(1,0) #,0.5)         glvertex2f(1.0, -1.0);         gltexcoord2f(1,1) #,0.5)         glvertex2f(1.0, 1.0);         gltexcoord2f(0,1) #,0.5)         glvertex2f(-1.0, 1.0);         glend();         glbindtexture( gl_texture_2d, 0 )        def resizegl(self, widthinpixels, heightinpixels):         if ((widthinpixels not self.uwidth) or (heightinpixels not self.uheight)):                     self.uwidth = widthinpixels             self.uheight = heightinpixels              glviewport(0, 0, widthinpixels, heightinpixels)             self.update()   class testimageloadstore2d(qtgui.qmainwindow):     def __init__(self):         qtgui.qmainwindow.__init__(self)         self.setwindowtitle('testimageloadstore2d')         self.statusbar().showmessage("hello there")          exit = qtgui.qaction("exit", self)         exit.setshortcut("ctrl+q")         exit.setstatustip('exit application')         self.connect(exit, qtcore.signal('triggered()'), qtcore.slot('close()'))           self.viewer3d = viewer3dwidget(self)          self.setcentralwidget(self.viewer3d)          self.resize(500,500)      def closeevent(self, event):         event.accept()   if __name__ == '__main__':     # app = qtgui.qapplication(['python qt opengl demo'])     app = qtgui.qapplication(sys.argv)     window = testimageloadstore2d()     window.show()     sys.exit(app.exec_()) 

while non-working 3d version following:

#! /usr/bin/env python  pyqt4 import qtgui, qtcore pyqt4.qtopengl import * opengl.gl import * opengl.glu import * import sys itexsize = 256   _vsclearsource =  """     #version 440 compatibility     void main() {         gl_position = ftransform();         gl_frontcolor = gl_color;     }     """       _fsclearsource =   """ #version 440 compatibility uniform int         iprimitivecount; uniform int         isliceindex;  layout(size4x32, binding=0) writeonly uniform   image3d volcolorvolume; //layout(rgba32f, binding=0) writeonly uniform   image3d volcolorvolume; const int imaxtexsize = 255;    void main() {     ivec3 ivecvolumecoordinate = ivec3(gl_fragcoord.x, gl_fragcoord.y, 0); //isliceindex);      vec4 vecvolumevalue =  vec4(0,1,0,1); // vec4(         float(islabindex)/float(iprimitivecount)); //,0.0,0.0,0.0);     imagestore(volcolorvolume, ivecvolumecoordinate, vecvolumevalue);     memorybarrier();                     gl_fragdata[0] = vec4(1,0,1,1); }         """      _fsfillsource =   """ #version 440 compatibility uniform int         iprimitivecount; uniform int         isliceindex;  layout(size4x32, binding=0) writeonly uniform   image3d volcolorvolume; const int imaxtexsize = 255;    void main() {     ivec3 ivecvolumecoordinate = ivec3(gl_fragcoord.x, gl_fragcoord.y, 0); //isliceindex);      vec4 vecvolumevalue =  vec4( float(gl_fragcoord.x)  / float(imaxtexsize)  , float(gl_fragcoord.y)  / float(imaxtexsize)  , float(isliceindex)/float(iprimitivecount) ,  1  );     imagestore(volcolorvolume, ivecvolumecoordinate, vecvolumevalue);       memorybarrier();                   gl_fragdata[0] = vec4(1,0,1,1); }     """           class viewer3dwidget(qglwidget):      def __init__(self, parent):         qglwidget.__init__(self, parent)          self.uwidth = 0         self.uheight = 0          self.texcolortexture = none         self.fborendering    = none         self.texcolorvolume = none          self.vecbackgroundcolor = (1.,1.,1.)          self.vecdrawbuffers = [ gl_color_attachment0 , gl_color_attachment1 , gl_color_attachment2, gl_color_attachment3, gl_color_attachment4, gl_color_attachment5 ]           self.fsurfacesspacing = 1.0         self.fsurfacestransparency = 1.0         self.fzcoord = 0.0       def setzcoordinate(self, fzcoordinate):         self.fzcoord = fzcoordinate         self.update()        def initializegl(self):         self.shashaderfill = qglshaderprogram(self.context())         self.shashaderfill.addshaderfromsourcecode(qglshader.vertex, _vsclearsource)         self.shashaderfill.addshaderfromsourcecode(qglshader.fragment, _fsfillsource)            self.shashaderfill.link()                self.shashaderclear = qglshaderprogram(self.context())         self.shashaderclear.addshaderfromsourcecode(qglshader.vertex, _vsclearsource)         self.shashaderclear.addshaderfromsourcecode(qglshader.fragment, _fsclearsource)            self.shashaderclear.link()                   glclearcolor(1.0, 1.0, 1.0, 1.0)         glcleardepth(1.0)       def initrendertargets(self):         global itexsize         if (self.texcolortexture none):             self.texcolortexture = glgentextures( 1 )         if (self.fborendering  none):             self.fborendering = glgenframebuffers(1)                         glbindtexture( gl_texture_rectangle, self.texcolortexture )         gltexparameteri(gl_texture_rectangle, gl_texture_wrap_s, gl_clamp)         gltexparameteri(gl_texture_rectangle, gl_texture_wrap_t, gl_clamp)         gltexparameteri(gl_texture_rectangle, gl_texture_min_filter, gl_nearest)         gltexparameteri(gl_texture_rectangle, gl_texture_mag_filter, gl_nearest)         glteximage2d(gl_texture_rectangle, 0, gl_rgba32f, itexsize, itexsize, 0, gl_rgba, gl_float, none)           glbindtexture(gl_texture_rectangle, 0);          glbindframebuffer(gl_framebuffer, self.fborendering)         glframebuffertexture2d(gl_framebuffer, gl_color_attachment0, gl_texture_rectangle,  self.texcolortexture, 0)         glbindframebuffer(gl_framebuffer, 0)           def deleterendertargets(self):         if (self.fboaccumulation  not  none):             gldeleteframebuffers(1,self.fborendering)                       self.fboaccumulation = none         if (self.texcolortexture not none):             gldeletetextures( self.texcolortexture )             self.texcolortexture = none       def initcolorvolume(self):         if (self.texcolorvolume none):             self.texcolorvolume = glgentextures( 1 )           glbindtexture( gl_texture_3d, self.texcolorvolume )         gltexparameteri(gl_texture_3d, gl_texture_wrap_s, gl_clamp)         gltexparameteri(gl_texture_3d, gl_texture_wrap_t, gl_clamp)         gltexparameteri(gl_texture_3d, gl_texture_wrap_r, gl_clamp)         gltexparameteri(gl_texture_3d, gl_texture_min_filter, gl_nearest)         gltexparameteri(gl_texture_3d, gl_texture_mag_filter, gl_nearest)         glteximage3d(gl_texture_3d, 0, gl_rgba32f, itexsize, itexsize, itexsize, 0, gl_rgba, gl_float, none);           glbindtexture(gl_texture_3d, 0);            def fillvolume(self, bclear):         global itexsize          shashader = self.shashaderclear         if(not bclear):             shashader = self.shashaderfill          if (not self.fborendering):             self.initrendertargets()           if (not self.texcolorvolume):             self.initcolorvolume()          glmatrixmode( gl_projection )         glloadidentity()          glmatrixmode( gl_modelview );         glloadidentity();                        glbindimagetexture(0,self.texcolorvolume,0,gl_false,0,gl_write_only,gl_rgba32f);          glbindframebuffer(gl_framebuffer, self.fborendering);         gldrawbuffers(1, self.vecdrawbuffers);          glclearcolor(0, 0, 0, 0);         glclear(gl_color_buffer_bit);                      shashader.bind()          shashader.setuniformvalue("iprimitivecount", itexsize)           shashader.setuniformvalue("volcolorvolume", 0)           in range(itexsize):               shashader.setuniformvalue("isliceindex", i)                  glbegin(gl_quads);             glvertex2f(-1.0, -1.0);              glvertex2f(1.0, -1.0);             glvertex2f(1.0, 1.0);             glvertex2f(-1.0, 1.0);             glend();               #sync             glmemorybarrier(gl_all_barrier_bits);         glmemorybarrier(gl_all_barrier_bits);          glbindimagetexture(0,0,0,gl_false,0,gl_write_only,gl_rgba32f);         shashader.release()          glbindframebuffer(gl_framebuffer, 0);       def paintgl(self):         if  (self.uwidth 0):             return                    if (not self.fborendering):             self.initrendertargets()              self.initcolorvolume()          glmatrixmode( gl_projection )         glloadidentity()          glmatrixmode( gl_modelview );         glloadidentity();          glclear(gl_color_buffer_bit | gl_depth_buffer_bit)           self.fillvolume(true)         #draw volume         #self.fillvolume(false)          #slice volume         self.displaytexture()            glflush()         def displaytexture(self):   #essentially not useable here         glmatrixmode( gl_projection )         glloadidentity()         glmatrixmode( gl_modelview );         glloadidentity();         gldisable(gl_blend)         gldisable(gl_depth_test);           gldisable(gl_lighting)          glclear(gl_color_buffer_bit | gl_depth_buffer_bit)         glcolor(1.0, 1.0,1.0)            glenable(gl_texture_3d);          glbindtexture( gl_texture_3d, self.texcolorvolume )          fzcoord = self.fzcoord                  glbegin(gl_quads);         gltexcoord3f(0,0,fzcoord)         glvertex2f(-1.0, -1.0);          gltexcoord3f(1,0,fzcoord)         glvertex2f(1.0, -1.0);         gltexcoord3f(1,1,fzcoord)         glvertex2f(1.0, 1.0);         gltexcoord3f(0,1,fzcoord)         glvertex2f(-1.0, 1.0);         glend();         glbindtexture( gl_texture_3d, 0 )        def resizegl(self, widthinpixels, heightinpixels):         if ((widthinpixels not self.uwidth) or (heightinpixels not self.uheight)):                     self.uwidth = widthinpixels             self.uheight = heightinpixels              glviewport(0, 0, widthinpixels, heightinpixels)             self.update()      class testimageloadstore3d(qtgui.qmainwindow):     def __init__(self):         qtgui.qmainwindow.__init__(self)         self.setwindowtitle('testimageloadstore3d')         self.statusbar().showmessage("hello there")          exit = qtgui.qaction("exit", self)         exit.setshortcut("ctrl+q")         exit.setstatustip('exit application')         self.connect(exit, qtcore.signal('triggered()'), qtcore.slot('close()'))           self.settooltip('this window, or <b>something</b>')          self.viewer3d = viewer3dwidget(self)          parentwidget = qtgui.qwidget()         slider1 = qtgui.qslider(qtcore.qt.horizontal, none)         slider1.setrange(0,10000)         slider1.setvalue(5000)         slider1.setmaximumwidth(120)         slider1.valuechanged.connect(self.slider1handler)         vbox = qtgui.qvboxlayout()         vbox.addwidget(slider1)         vbox.addstretch(1)         self.viewer3d.setsizepolicy( qtgui.qsizepolicy.expanding, qtgui.qsizepolicy.expanding )         hbox = qtgui.qhboxlayout()         hbox.addlayout(vbox)         hbox.addwidget(self.viewer3d)          parentwidget.setlayout(hbox)                 self.setcentralwidget(parentwidget)           self.resize(500,500)      def closeevent(self, event):         event.accept()     def slider1handler(self, ival):             fval = ival / 10000.0         #print "zcoord: ",fval         self.viewer3d.setzcoordinate(fval)             if __name__ == '__main__':     # app = qtgui.qapplication(['python qt opengl demo'])     app = qtgui.qapplication(sys.argv)     window = testimageloadstore3d()     window.show()     sys.exit(app.exec_()) 

the code not neat, because copy/pasted/modified older pyopengl code had. problem values written in 3d texture make absolute no sense. ran using latest version of pyopengl (the experimental one), quadro k5000 , latest drivers (332.76), provide support opengl 4.4 .

i'm not sure might doing wrong, because haven't found many examples of writing 3d textures (actually none, , looked in latest version of red book)

can enlighten me?

your problem here in frag shader:

layout(size4x32, binding=0) writeonly uniform   image3d volcolorvolume; 

you binding 3d texture via

glbindimagetexture(0,self.texcolorvolume,0,gl_false,0,gl_write_only,gl_rgba32f); 

let me quote opengl 4.4 spec, section 8.26 "texture image loads , stores" (emphasis mine):

if texture identified texture one-dimensional array, two-dimensional array, three-dimensional, cube map, cube map array, or two-dimensional multisample array texture, possible bind either entire texture level or single layer or face of texture level. if layered true, entire level bound. if layered false, single layer identified layer bound. when layered false, single bound layer treated different texture target image accesses:

  • one-dimensional array texture layers treated one-dimensional textures;
  • two-dimensional array, three-dimensional, cube map, cube map array texture layers treated two-dimensional textures; and
  • two-dimensional multisample array textures treated two-dimensional multisample textures.

so, if bind 1 layer of 3d texture layered parameter set gl_false (as doing), act if 2d texture, either use image2d , access 2d coords, or bind layered set gl_true , valid range of layers able write specific layer/slices of texture using image3d , 3-dimensional image coordinates.


Comments

Popular posts from this blog

PHPMotion implementation - URL based videos (Hosted on separate location) -

javascript - Using Windows Media Player as video fallback for video tag -

c# - Unity IoC Lifetime per HttpRequest for UserStore -