def init_back_texture(self, width, height): if self.fbo is None: self.fbo = glGenFramebuffers(1) glActiveTexture(GL_TEXTURE0 + 1) if self.bfTex is not None: glDeleteTextures([self.bfTex]) self.bfTex = glGenTextures(1) glBindTexture(GL_TEXTURE_2D, self.bfTex) glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) w = int(width) h = int(height) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, w, h, 0, GL_RGBA, GL_FLOAT, None) glBindFramebuffer(GL_FRAMEBUFFER, self.fbo) glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, self.bfTex, 0) glBindFramebuffer(GL_FRAMEBUFFER, 0) glBindTexture(GL_TEXTURE_2D, 0)
def create(self): """ creates the fbo, call only once after configuration done. you have to add textures before. """ self.hasColor = self.colorTextures != [] self.hasDepth = self.depthTexture != None self.hasStencil = self.stencilTexture != None self.hasDepthStencil = self.depthStencilTexture != None self.depthOnly = self.hasDepth and not self.hasColor # create and bind fbo self.glFBO = glFBO.glGenFramebuffers(1) glFBO.glBindFramebuffer(glFBO.GL_FRAMEBUFFER, self.glFBO) if self.depthOnly: # only draw depth gl.glDrawBuffer(gl.GL_NONE) gl.glReadBuffer(gl.GL_NONE) # add textures for i in range(len(self.colorTextures)): tex = self.colorTextures[i] glFBO.glFramebufferTexture2D(glFBO.GL_FRAMEBUFFER, glFBO.GL_COLOR_ATTACHMENT0+i, tex.targetType, tex.glID, 0) if self.hasDepth: glFBO.glFramebufferTexture2D(glFBO.GL_FRAMEBUFFER, glFBO.GL_DEPTH_ATTACHMENT, self.depthTexture.targetType, self.depthTexture.glID, 0) if self.hasStencil: glFBO.glFramebufferTexture2D(glFBO.GL_FRAMEBUFFER, glFBO.GL_STENCIL_ATTACHMENT, self.stencilTexture.targetType, self.stencilTexture.glID, 0) if self.hasDepthStencil: glFBO.glFramebufferTexture2D(glFBO.GL_FRAMEBUFFER, glFBO.GL_DEPTH_STENCIL_ATTACHMENT, self.depthStencilTexture.targetType, self.depthStencilTexture.glID, 0) # check if everything is ok with the fbo self.checkError() # release fbo glFBO.glBindFramebuffer(glFBO.GL_FRAMEBUFFER, 0) # remember color buffers if self.colorTextures != []: self.numBuffers = len(self.colorTextures) data = map(lambda x: glFBO.GL_COLOR_ATTACHMENT0+x, range(self.numBuffers)) self.colorBuffers = NumpyArray(data, "I")
def __init__(self, width, height, drawFunc): tex = GL.glGenTextures(1) GL.glBindTexture(GL.GL_TEXTURE_2D, tex) GL.glTexParameter(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST) GL.glTexParameter(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST) GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA8, width, height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, None) self.enabled = False self._texID = tex if bool(FBO.glGenFramebuffers) and "Intel" not in GL.glGetString(GL.GL_VENDOR): buf = FBO.glGenFramebuffers(1) depthbuffer = FBO.glGenRenderbuffers(1) FBO.glBindFramebuffer(FBO.GL_FRAMEBUFFER, buf) FBO.glBindRenderbuffer(FBO.GL_RENDERBUFFER, depthbuffer) FBO.glRenderbufferStorage(FBO.GL_RENDERBUFFER, GL.GL_DEPTH_COMPONENT, width, height) FBO.glFramebufferRenderbuffer(FBO.GL_FRAMEBUFFER, FBO.GL_DEPTH_ATTACHMENT, FBO.GL_RENDERBUFFER, depthbuffer) FBO.glFramebufferTexture2D(FBO.GL_FRAMEBUFFER, FBO.GL_COLOR_ATTACHMENT0, GL.GL_TEXTURE_2D, tex, 0) status = FBO.glCheckFramebufferStatus(FBO.GL_FRAMEBUFFER) if status != FBO.GL_FRAMEBUFFER_COMPLETE: print "glCheckFramebufferStatus", status self.enabled = False return FBO.glBindFramebuffer(FBO.GL_FRAMEBUFFER, buf) with gl.glPushAttrib(GL.GL_VIEWPORT_BIT): GL.glViewport(0, 0, width, height) drawFunc() FBO.glBindFramebuffer(FBO.GL_FRAMEBUFFER, 0) FBO.glDeleteFramebuffers(1, [buf]) FBO.glDeleteRenderbuffers(1, [depthbuffer]) self.enabled = True else: GL.glReadBuffer(GL.GL_BACK) if bool(window_pos.glWindowPos2dARB): pixels = GL.glReadPixels(0, 0, width, height, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE) GL.glPushAttrib(GL.GL_VIEWPORT_BIT | GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_TEST | GL.GL_STENCIL_BUFFER_BIT) GL.glDisable(GL.GL_STENCIL_TEST) GL.glViewport(0, 0, width, height) GL.glScissor(0, 0, width, height) with gl.glEnable(GL.GL_SCISSOR_TEST): drawFunc() GL.glBindTexture(GL.GL_TEXTURE_2D, tex) GL.glReadBuffer(GL.GL_BACK) GL.glCopyTexSubImage2D(GL.GL_TEXTURE_2D, 0, 0, 0, 0, 0, width, height) if bool(window_pos.glWindowPos2dARB): window_pos.glWindowPos2dARB(0,0) GL.glDrawPixels(width, height, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, pixels) GL.glPopAttrib()
def renderToArray(self, size, format=GL_BGRA, type=GL_UNSIGNED_BYTE, textureSize=1024, padding=256): w,h = map(int, size) self.makeCurrent() tex = None fb = None try: output = np.empty((w, h, 4), dtype=np.ubyte) fb = glfbo.glGenFramebuffers(1) glfbo.glBindFramebuffer(glfbo.GL_FRAMEBUFFER, fb ) glEnable(GL_TEXTURE_2D) tex = glGenTextures(1) glBindTexture(GL_TEXTURE_2D, tex) texwidth = textureSize data = np.zeros((texwidth,texwidth,4), dtype=np.ubyte) ## Test texture dimensions first glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGBA, texwidth, texwidth, 0, GL_RGBA, GL_UNSIGNED_BYTE, None) if glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH) == 0: raise Exception("OpenGL failed to create 2D texture (%dx%d); too large for this hardware." % shape[:2]) ## create teture glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texwidth, texwidth, 0, GL_RGBA, GL_UNSIGNED_BYTE, data.transpose((1,0,2))) self.opts['viewport'] = (0, 0, w, h) # viewport is the complete image; this ensures that paintGL(region=...) # is interpreted correctly. p2 = 2 * padding for x in range(-padding, w-padding, texwidth-p2): for y in range(-padding, h-padding, texwidth-p2): x2 = min(x+texwidth, w+padding) y2 = min(y+texwidth, h+padding) w2 = x2-x h2 = y2-y ## render to texture glfbo.glFramebufferTexture2D(glfbo.GL_FRAMEBUFFER, glfbo.GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0) self.paintGL(region=(x, h-y-h2, w2, h2), viewport=(0, 0, w2, h2)) # only render sub-region glBindTexture(GL_TEXTURE_2D, tex) # fixes issue #366 ## read texture back to array data = glGetTexImage(GL_TEXTURE_2D, 0, format, type) data = np.fromstring(data, dtype=np.ubyte).reshape(texwidth,texwidth,4).transpose(1,0,2)[:, ::-1] output[x+padding:x2-padding, y+padding:y2-padding] = data[padding:w2-padding, -(h2-padding):-padding] finally: self.opts['viewport'] = None glfbo.glBindFramebuffer(glfbo.GL_FRAMEBUFFER, 0) glBindTexture(GL_TEXTURE_2D, 0) if tex is not None: glDeleteTextures([tex]) if fb is not None: glfbo.glDeleteFramebuffers([fb]) return output
def initializeGL(self): super(AbstractCam, self).initializeGL() print '[cam] initializeGL(): hello' self.mode_polygon = GL_FILL self.tex = glGenTextures(1) print '[cam] self.tex: %s' % self.tex # ref: songho/fboDepth/main.cpp glBindTexture(GL_TEXTURE_2D, self.tex) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) #glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) #glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP) #glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE) # use None for 0 in PyOpenGL !! # glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, # self.viewport_width, self.viewport_height, # 0, GL_RGBA, GL_UNSIGNED_BYTE, None) glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, # self.viewport_width, self.viewport_height, # broken image 640, 640, # fixme: how to get correct 640x480 depth texture? 0, GL_DEPTH_COMPONENT, GL_FLOAT, None) #glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, self.viewport_width, self.viewport_height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, None) glBindTexture(GL_TEXTURE_2D, 0) # unbind self.fbo = glfbo.glGenFramebuffers(1) print '[cam] self.fbo: %s' % self.fbo glfbo.glBindFramebuffer(glfbo.GL_FRAMEBUFFER, self.fbo) # the last arg is mipmap level. http://pyopengl.sourceforge.net/documentation/manual-3.0/glFramebufferTexture.html glfbo.glFramebufferTexture2D(glfbo.GL_FRAMEBUFFER, glfbo.GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, self.tex, 0) glDrawBuffer(GL_NONE) glReadBuffer(GL_NONE) glfbo.glBindFramebuffer(glfbo.GL_FRAMEBUFFER, 0) # unbind if 1: AbstractCam.set_mat_proj_xtion() else: glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(90.0, 1.0, 1.0, 100.0)
def __init__(self, width, height, drawFunc): tex = GL.glGenTextures(1) GL.glBindTexture(GL.GL_TEXTURE_2D, tex) GL.glTexParameter(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST) GL.glTexParameter(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST) GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA8, width, height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, None) self.enabled = False self._texID = tex if bool(FBO.glGenFramebuffers) and "Intel" not in GL.glGetString(GL.GL_VENDOR): buf = FBO.glGenFramebuffers(1) depthbuffer = FBO.glGenRenderbuffers(1) FBO.glBindFramebuffer(FBO.GL_FRAMEBUFFER, buf) FBO.glBindRenderbuffer(FBO.GL_RENDERBUFFER, depthbuffer) FBO.glRenderbufferStorage(FBO.GL_RENDERBUFFER, GL.GL_DEPTH_COMPONENT, width, height) FBO.glFramebufferRenderbuffer(FBO.GL_FRAMEBUFFER, FBO.GL_DEPTH_ATTACHMENT, FBO.GL_RENDERBUFFER, depthbuffer) FBO.glFramebufferTexture2D(FBO.GL_FRAMEBUFFER, FBO.GL_COLOR_ATTACHMENT0, GL.GL_TEXTURE_2D, tex, 0) status = FBO.glCheckFramebufferStatus(FBO.GL_FRAMEBUFFER) if status != FBO.GL_FRAMEBUFFER_COMPLETE: print ("glCheckFramebufferStatus: " + str(status)) self.enabled = False return FBO.glBindFramebuffer(FBO.GL_FRAMEBUFFER, buf) with gl.glPushAttrib(GL.GL_VIEWPORT_BIT): GL.glViewport(0, 0, width, height) drawFunc() FBO.glBindFramebuffer(FBO.GL_FRAMEBUFFER, 0) FBO.glDeleteFramebuffers(1, [buf]) FBO.glDeleteRenderbuffers(1, [depthbuffer]) self.enabled = True else: GL.glReadBuffer(GL.GL_BACK) GL.glPushAttrib(GL.GL_VIEWPORT_BIT | GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_TEST | GL.GL_STENCIL_BUFFER_BIT) GL.glDisable(GL.GL_STENCIL_TEST) GL.glViewport(0, 0, width, height) GL.glScissor(0, 0, width, height) with gl.glEnable(GL.GL_SCISSOR_TEST): drawFunc() GL.glBindTexture(GL.GL_TEXTURE_2D, tex) GL.glReadBuffer(GL.GL_BACK) GL.glCopyTexSubImage2D(GL.GL_TEXTURE_2D, 0, 0, 0, 0, 0, width, height) GL.glPopAttrib()
def create(self, app): """ creates resources. """ self.app = app shadowMaps = self.shadowMaps # reserve a texture unit for shadow texture self.textureUnit = app.reserveTextureUnit() # create a 3D texture using GL_TEXTURE_2D_ARRAY self.texture = DepthTexture3D(self.sizeI, self.sizeI) self.texture.targetType = GL_TEXTURE_2D_ARRAY self.texture.internalFormat = GL_DEPTH_COMPONENT24 self.texture.numTextures = self.numShadowMaps self.texture.pixelType = GL_FLOAT self.texture.minFilterMode = GL_LINEAR self.texture.magFilterMode = GL_LINEAR self.texture.wrapMode = GL_CLAMP_TO_EDGE self.texture.compareFunc = GL_LEQUAL if self.textureType=="sampler2DArrayShadow": self.texture.compareMode = GL_COMPARE_R_TO_TEXTURE else: self.texture.compareMode = GL_NONE self.texture.create() # create a depth only fbo for the 3D texture self.fbo = glGenFramebuffers(1) glBindFramebuffer(GL_FRAMEBUFFER, self.fbo) glDrawBuffer(GL_NONE) glBindFramebuffer(GL_FRAMEBUFFER, 0) # the frustum slice far value must be accessable in the shader. # uniforms does not support array, so we split # the frustum slices in vec4 instances.... numVecs = self.numShadowMaps/4; mod = self.numShadowMaps%4 self.farVecs = [4]*numVecs if mod != 0: self.farVecs.append( mod ) numVecs += 1 # create shadow maps for i in range(self.numShadowMaps): shadowMap = shadowMaps[i] shadowMap.textureMatrixUnit = app.reserveTextureMatrixUnit() shadowMap.textureLayer = i shadowMap.create(app)
def glCreateFramebuffer(): return FBO.glGenFramebuffers(1)
def __init__(self, width, height): self._width = width self._height = height self._id = -1 self._id = glfbo.glGenFramebuffers(1) self._depthbuffer = -1