简体   繁体   English

用于3D纹理的OpenGL 4.2+和shader_image_load_store不起作用?

[英]OpenGL 4.2+ and shader_image_load_store for 3D textures not working?

I am trying to figure out why I'm not able to write into 3D textures using the (now built-in) shader_image_load_store extension. 我试图弄清楚为什么我无法使用(现在内置的)shader_image_load_store扩展名写入3D纹理。

I created two simple examples (in python to make it easier): one to write into a 2D texture, that works, and one to write into a 3D texture that does not work 我创建了两个简单的示例(使用python使其更容易实现):一个示例写入有效的2D纹理,另一个示例写入无效的3D纹理

the (working) 2D version is as following: (工作中的)2D版本如下:

#! /usr/bin/env python

from PyQt4 import QtGui, QtCore
from PyQt4.QtOpenGL import *
from OpenGL.GL import *
from 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 is None):
            self.texColorTexture = glGenTextures( 1 )
        if (self.fboRendering is  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 is  not  None):
            glDeleteFramebuffers(1,self.fboRendering)          
            self.fboAccumulation = None
        if (self.texColorTexture is not None):
            glDeleteTextures( self.texColorTexture )
            self.texColorTexture = None


    def initColorVolume(self):
        if (self.texColorVolume is 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) 

        for i 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 is 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 into the volume
        self.fillVolume(False)

        #slice the 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 is not self.uWidth) or (heightInPixels is 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 the non-working 3D version is as following: 无效的3D版本如下:

#! /usr/bin/env python

from PyQt4 import QtGui, QtCore
from PyQt4.QtOpenGL import *
from OpenGL.GL import *
from 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 is None):
            self.texColorTexture = glGenTextures( 1 )
        if (self.fboRendering is  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 is  not  None):
            glDeleteFramebuffers(1,self.fboRendering)          
            self.fboAccumulation = None
        if (self.texColorTexture is not None):
            glDeleteTextures( self.texColorTexture )
            self.texColorTexture = None


    def initColorVolume(self):
        if (self.texColorVolume is 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) 

        for i 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 is 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 into the volume
        #self.fillVolume(False)

        #slice the 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 is not self.uWidth) or (heightInPixels is 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 is a 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 is not extra neat, also because i copy/pasted/modified some older pyopengl code i had. 该代码不是特别整洁,也是因为我复制/粘贴/修改了我的一些旧的pyopengl代码。 The problem is that the values written in the 3D texture make absolute no sense. 问题在于以3D纹理写入的值绝对没有意义。 I ran it using the latest version of PyOpenGL (the experimental one), a Quadro K5000 and the latest drivers (332.76), that also provide the support for OpenGL 4.4 . 我使用最新版本的PyOpenGL(实验版本),Quadro K5000和最新的驱动程序(332.76)来运行它,它们也提供对OpenGL 4.4的支持。

I'm not sure what i might be doing wrong, also because i haven't found many examples of writing into 3D textures (actually none, and i also looked in the latest version of the red book) 我不确定自己可能做错了什么,也因为我没有发现很多写3D纹理的示例(实际上没有,而且我也在看红皮书的最新版本)

Can someone enlighten me? 有人可以启发我吗?

Your problem is here in your frag shader: 您的问题在您的片段着色器中:

layout(size4x32, binding=0) writeonly uniform   image3D volColorVolume;

You are binding the 3D texture via 您正在通过绑定3D纹理

glBindImageTexture(0,self.texColorVolume,0,GL_FALSE,0,GL_WRITE_ONLY,GL_RGBA32F);

Let me quote from the OpenGL 4.4 spec, section 8.26 "Texture Image Loads and Stores" (emphasis mine): 让我引用OpenGL 4.4规范的第8.26节“纹理图像的加载和存储”(重点是我的):

If the texture identified by texture is a one-dimensional array, two-dimensional array, three-dimensional, cube map, cube map array, or two-dimensional multisample array texture, it is possible to bind either the entire texture level or a single layer or face of the texture level. 如果由纹理标识的纹理是一维阵列,二维阵列,三维,立方体贴图,立方体贴图阵列或二维多样本阵列贴图,则可以绑定整个贴图级别或单个贴图层或面的纹理级别。 If layered is TRUE, the entire level is bound. 如果layered为TRUE,则绑定整个级别。 If layered is FALSE, only the single layer identified by layer will be bound. 如果layered为FALSE,则仅绑定由layer标识的单个层。 When layered is FALSE, the single bound layer is treated as a different texture target for image accesses: 如果layered为FALSE,则将单个绑定层视为图像访问的不同纹理目标:

  • one-dimensional array texture layers are treated as one-dimensional textures; 一维阵列纹理层被视为一维纹理;
  • two-dimensional array, three-dimensional , cube map, cube map array texture layers are treated as two-dimensional textures ; 二维阵列, 三维 ,立方体贴图,立方体贴图阵列纹理层被视为二维纹理 and
  • two-dimensional multisample array textures are treated as two-dimensional multisample textures. 二维多样本数组纹理被视为二维多样本纹理。

So, if you just bind one layer of a 3D texture with the layered parameter set to GL_FALSE (as you are currently doing), it will act as if it is just a 2D texture, so either just use an image2D and access it with 2D coords, or bind it with layered set to GL_TRUE and a valid range of layers you will be able to write into a specific layer/slices of your texture using an image3D and 3-dimensional image coordinates. 所以,如果你只是绑定3D纹理与一层layered设置参数GL_FALSE (因为你正在做的),它将作为,如果它仅仅是一个2D纹理,所以要么只使用一个image2D与2D访问它COORDS,或与它结合layered设置为GL_TRUE和层的一个有效范围,你将能够写入到特定层/你的纹理的切片使用image3D和3维图像的坐标。

you have like 60 semicolons in python. 您在python中有60个分号。 Python doesn't use semicolons. Python不使用分号。 In fact, I'm pretty sure python is the only programming language that actually doesn't use semicolons. 实际上,我非常确定python是唯一不使用分号的编程语言。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM