def render_planar_update(self, rx, ry, rw, rh, x_scale=1, y_scale=1): log("%s.render_planar_update%s pixel_format=%s", self, (rx, ry, rw, rh, x_scale, y_scale), self.pixel_format) if self.pixel_format not in ("YUV420P", "YUV422P", "YUV444P", "GBRP"): #not ready to render yet return if self.pixel_format == "GBRP": self.set_rgbP_paint_state() self.gl_marker("painting planar update, format %s", self.pixel_format) divs = get_subsampling_divs(self.pixel_format) glEnable(GL_FRAGMENT_PROGRAM_ARB) for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)): glActiveTexture(texture) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index]) tw, th = self.texture_size log("%s.render_planar_update(..) texture_size=%s, size=%s", self, self.texture_size, self.size) glBegin(GL_QUADS) for x,y in ((0, 0), (0, rh), (rw, rh), (rw, 0)): ax = min(tw, x) ay = min(th, y) for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)): (div_w, div_h) = divs[index] glMultiTexCoord2i(texture, ax//div_w, ay//div_h) glVertex2i(int(rx+ax*x_scale), int(ry+ay*y_scale)) glEnd() if self.pixel_format == "GBRP": self.unset_rgbP_paint_state()
def _do_paint_rgb24(self, img_data, x, y, w, h, rowstride, options, callbacks): log("do_paint_rgb24(%s bytes, %s, %s, %s, %s, %s, %s, %s)", len(img_data), x, y, w, h, rowstride, options, callbacks) ww, wh = self.size if x+w>ww or y+h>wh: log("do_paint_rgb24: ignoring paint which would overflow the backing area") return drawable = self.gl_init() if not drawable: log("do_paint_rgb24: cannot paint yet..") return try: #cleanup if we were doing yuv previously: if self.pixel_format!=GLPixmapBacking.RGB24: self.remove_shader() self.pixel_format = GLPixmapBacking.RGB24 glEnable(GL_TEXTURE_RECTANGLE_ARB) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[0]) glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstride/3) for texture in (GL_TEXTURE1, GL_TEXTURE2): glActiveTexture(texture) glDisable(GL_TEXTURE_RECTANGLE_ARB) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, w, h, GL_RGB, GL_UNSIGNED_BYTE, img_data) glBegin(GL_QUADS) for rx,ry in ((x, y), (x, y+h), (x+w, y+h), (x+w, y)): glTexCoord2i(rx, ry) glVertex2i(rx, ry) glEnd() finally: self.gl_end(drawable)
def render_planar_update(self, rx, ry, rw, rh, x_scale=1, y_scale=1): log("%s.render_planar_update%s pixel_format=%s", self, (rx, ry, rw, rh, x_scale, y_scale), self.pixel_format) if self.pixel_format not in ("YUV420P", "YUV422P", "YUV444P", "GBRP"): #not ready to render yet return if self.pixel_format == "GBRP": # Set GL state for planar RGB: change fragment program glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.shaders[RGBP2RGB_SHADER]) self.gl_marker("painting planar update, format %s", self.pixel_format) divs = get_subsampling_divs(self.pixel_format) glEnable(GL_FRAGMENT_PROGRAM_ARB) for texture, index in ((GL_TEXTURE0, TEX_Y), (GL_TEXTURE1, TEX_U), (GL_TEXTURE2, TEX_V)): glActiveTexture(texture) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index]) tw, th = self.texture_size log("%s.render_planar_update(..) texture_size=%s, size=%s", self, self.texture_size, self.size) glBegin(GL_QUADS) for x,y in ((0, 0), (0, rh), (rw, rh), (rw, 0)): ax = min(tw, x) ay = min(th, y) for texture, index in ((GL_TEXTURE0, TEX_Y), (GL_TEXTURE1, TEX_U), (GL_TEXTURE2, TEX_V)): (div_w, div_h) = divs[index] glMultiTexCoord2i(texture, ax//div_w, ay//div_h) glVertex2i(int(rx+ax*x_scale), int(ry+ay*y_scale)) glEnd() for texture in (GL_TEXTURE0, GL_TEXTURE1, GL_TEXTURE2): glActiveTexture(texture) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0) glDisable(GL_FRAGMENT_PROGRAM_ARB) if self.pixel_format == "GBRP": # Reset state to our default (YUV painting) glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.shaders[YUV2RGB_SHADER]) glActiveTexture(GL_TEXTURE0)
def swapBuffers(self): # first call the swap on the QGLWidget start = long(now() * 1000) self.glw.swapBuffers() #self.glw.makeCurrent() # The following is taken from the PsychToolbox # Draw a single pixel in left-top area of back-buffer. # This will wait/stall the rendering pipeline # until the buffer flip has happened, aka immediately after the VBL has started. # We need the pixel as "synchronization token", so the following glFinish() really # waits for VBL instead of just "falling through" due to the asynchronous nature of # OpenGL: glDrawBuffer(GL_BACK) # We draw our single pixel with an alpha-value of zero - so effectively it doesn't # change the color buffer - just the z-buffer if z-writes are enabled... glColor4f(0.0, 0.0, 0.0, 0.0) glBegin(GL_POINTS) glVertex2i(10, 10) glEnd() # This glFinish() will wait until point drawing is finished, ergo backbuffer was ready # for drawing, ergo buffer swap in sync with start of VBL has happened. glFinish() finish = long(now() * 1000) fdiff = finish - self.last_finish self.last_finish = finish return (start, finish - start, fdiff)
def swapBuffers(self): # first call the swap on the QGLWidget start = long(now()*1000) self.glw.swapBuffers() #self.glw.makeCurrent() # The following is taken from the PsychToolbox # Draw a single pixel in left-top area of back-buffer. # This will wait/stall the rendering pipeline # until the buffer flip has happened, aka immediately after the VBL has started. # We need the pixel as "synchronization token", so the following glFinish() really # waits for VBL instead of just "falling through" due to the asynchronous nature of # OpenGL: glDrawBuffer(GL_BACK) # We draw our single pixel with an alpha-value of zero - so effectively it doesn't # change the color buffer - just the z-buffer if z-writes are enabled... glColor4f(0.0,0.0,0.0,0.0) glBegin(GL_POINTS) glVertex2i(10,10) glEnd() # This glFinish() will wait until point drawing is finished, ergo backbuffer was ready # for drawing, ergo buffer swap in sync with start of VBL has happened. glFinish() finish = long(now()*1000) fdiff = finish - self.last_finish self.last_finish = finish return (start,finish-start,fdiff)
def render_yuv_update(self, rx, ry, rw, rh): debug("render_yuv_update %sx%s at %sx%s pixel_format=%s", rw, rh, rx, ry, self.pixel_format) if self.pixel_format not in (YUV420P, YUV422P, YUV444P): #not ready to render yet return self.gl_marker("Painting YUV update") divs = get_subsampling_divs(self.pixel_format) glEnable(GL_FRAGMENT_PROGRAM_ARB) glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.yuv_shader[0]) for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)): glActiveTexture(texture) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index]) tw, th = self.texture_size debug("render_yuv_update texture_size=%s, size=%s", self.texture_size, self.size) glBegin(GL_QUADS) for x, y in ((rx, ry), (rx, ry + rh), (rx + rw, ry + rh), (rx + rw, ry)): ax = min(tw, x) ay = min(th, y) for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)): (div_w, div_h) = divs[index] glMultiTexCoord2i(texture, ax / div_w, ay / div_h) glVertex2i(ax, ay) glEnd()
def draw_border(self): bw, bh = self.size #double size since half the line will be off-screen log("draw_border: %s", self.border) glLineWidth(self.border.size*2) glBegin(GL_LINE_LOOP) glColor4f(self.border.red, self.border.green, self.border.blue, self.border.alpha) for px,py in ((0, 0), (bw, 0), (bw, bh), (0, bh)): glVertex2i(px, py) glEnd()
def _do_paint_rgb24(self, img_data, x, y, width, height, rowstride, options, callbacks): debug( "%s._do_paint_rgb24(x=%d, y=%d, width=%d, height=%d, rowstride=%d)", self, x, y, width, height, rowstride) drawable = self.gl_init() if not drawable: debug("%s._do_paint_rgb24(..) drawable is not set!", self) return False try: self.set_rgb24_paint_state() # Compute alignment and row length row_length = 0 alignment = 1 for a in [2, 4, 8]: # Check if we are a-aligned - ! (var & 0x1) means 2-aligned or better, 0x3 - 4-aligned and so on if (rowstride & a - 1) == 0: alignment = a # If number of extra bytes is greater than the alignment value, # then we also have to set row_length # Otherwise it remains at 0 (= width implicitely) if (rowstride - width * 3) > a: row_length = width + (rowstride - width * 3) / 3 self.gl_marker( "RGB24 update at %d,%d, size %d,%d, stride is %d, row length %d, alignment %d" % (x, y, width, height, rowstride, row_length, alignment)) # Upload data as temporary RGB texture glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_RGB]) glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length) glPixelStorei(GL_UNPACK_ALIGNMENT, alignment) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data) # Draw textured RGB quad at the right coordinates glBegin(GL_QUADS) glTexCoord2i(0, 0) glVertex2i(x, y) glTexCoord2i(0, height) glVertex2i(x, y + height) glTexCoord2i(width, height) glVertex2i(x + width, y + height) glTexCoord2i(width, 0) glVertex2i(x + width, y) glEnd() # Present update to screen self.present_fbo(drawable) # present_fbo has reset state already finally: drawable.gl_end() return True
def render_image(self, rx, ry, rw, rh): log("render_image %sx%s at %sx%s pixel_format=%s", rw, rh, rx, ry, self.pixel_format) if self.pixel_format not in (YUV420P, YUV422P, YUV444P): #not ready to render yet return divs = self.get_subsampling_divs(self.pixel_format) glEnable(GL_FRAGMENT_PROGRAM_ARB) glBegin(GL_QUADS) for x,y in ((rx, ry), (rx, ry+rh), (rx+rw, ry+rh), (rx+rw, ry)): for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)): div = divs[index] glMultiTexCoord2i(texture, x/div, y/div) glVertex2i(x, y) glEnd() glFlush()
def draw(self): vertices = self.get_vertices() glColor3ub(*self.color) glBegin(GL_QUADS) glVertex2i(*vertices["tl"]) glVertex2i(*vertices["bl"]) glVertex2i(*vertices["br"]) glVertex2i(*vertices["tr"]) glEnd()
def paint_box(self, encoding, is_delta, x, y, w, h): #show region being painted if debug paint box is enabled only: if self.paint_box_line_width<=0: return glLineWidth(self.paint_box_line_width+0.5+int(encoding=="scroll")*2) if is_delta: glLineStipple(1, 0xaaaa) glEnable(GL_LINE_STIPPLE) glBegin(GL_LINE_LOOP) color = get_paint_box_color(encoding) log("Painting colored box around %s screen update using: %s (delta=%s)", encoding, color, is_delta) glColor4f(*color) for px,py in ((x, y), (x+w, y), (x+w, y+h), (x, y+h)): glVertex2i(px, py) glEnd() if is_delta: glDisable(GL_LINE_STIPPLE)
def do_paint_rgb(self, rgb_format, img_data, x, y, width, height, rowstride, options, callbacks): log("%s.do_paint_rgb(%s, %s bytes, x=%d, y=%d, width=%d, height=%d, rowstride=%d, options=%s)", self, rgb_format, len(img_data), x, y, width, height, rowstride, options) context = self.gl_context() if not context: log("%s._do_paint_rgb(..) no context!", self) fire_paint_callbacks(callbacks, False, "no opengl context") return if not options.get("paint", True): fire_paint_callbacks(callbacks) return try: upload, img_data = self.pixels_for_upload(img_data) with context: self.gl_init() self.set_rgb_paint_state() #convert it to a GL constant: pformat = PIXEL_FORMAT_TO_CONSTANT.get(rgb_format.decode()) assert pformat is not None, "could not find pixel format for %s" % rgb_format self.gl_marker("%s update at (%d,%d) size %dx%d (%s bytes), using GL %s format=%s", rgb_format, x, y, width, height, len(img_data), upload, CONSTANT_TO_PIXEL_FORMAT.get(pformat)) # Upload data as temporary RGB texture glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_RGB]) self.set_alignment(width, rowstride, rgb_format) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST) set_texture_level() glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, self.texture_pixel_format, width, height, 0, pformat, GL_UNSIGNED_BYTE, img_data) # Draw textured RGB quad at the right coordinates glBegin(GL_QUADS) glTexCoord2i(0, 0) glVertex2i(x, y) glTexCoord2i(0, height) glVertex2i(x, y+height) glTexCoord2i(width, height) glVertex2i(x+width, y+height) glTexCoord2i(width, 0) glVertex2i(x+width, y) glEnd() self.paint_box(options.get("encoding"), options.get("delta", -1)>=0, x, y, width, height) # Present update to screen self.present_fbo(x, y, width, height, options.get("flush", 0)) # present_fbo has reset state already fire_paint_callbacks(callbacks) except Exception as e: log("Error in %s paint of %i bytes, options=%s)", rgb_format, len(img_data), options) fire_paint_callbacks(callbacks, False, "OpenGL %s paint error: %s" % (rgb_format, e))
def render_image(self, rx, ry, rw, rh): log("render_image %sx%s at %sx%s pixel_format=%s", rw, rh, rx, ry, self.pixel_format) if self.pixel_format not in (YUV420P, YUV422P, YUV444P): #not ready to render yet return divs = self.get_subsampling_divs(self.pixel_format) glEnable(GL_FRAGMENT_PROGRAM_ARB) glBegin(GL_QUADS) for x, y in ((rx, ry), (rx, ry + rh), (rx + rw, ry + rh), (rx + rw, ry)): for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)): div = divs[index] glMultiTexCoord2i(texture, x / div, y / div) glVertex2i(x, y) glEnd() glFlush()
def paint_box(self, encoding, is_delta, x, y, w, h): #show region being painted if debug paint box is enabled only: if self.paint_box_line_width<=0: return glDisable(GL_TEXTURE_RECTANGLE_ARB) glDisable(GL_FRAGMENT_PROGRAM_ARB) glLineWidth(self.paint_box_line_width+0.5) if is_delta: glLineStipple(1, 0xaaaa) glEnable(GL_LINE_STIPPLE) glBegin(GL_LINE_LOOP) color = BOX_COLORS.get(encoding, _DEFAULT_BOX_COLOR) log("Painting colored box around %s screen update using: %s (delta=%s)", encoding, color, is_delta) glColor4f(*color) for px,py in ((x, y), (x+w, y), (x+w, y+h), (x, y+h)): glVertex2i(px, py) glEnd() if is_delta: glDisable(GL_LINE_STIPPLE)
def paint_box(self, encoding, is_delta, x, y, w, h): #show region being painted if debug paint box is enabled only: if not OPENGL_PAINT_BOX>0: return glDisable(GL_TEXTURE_RECTANGLE_ARB) glDisable(GL_FRAGMENT_PROGRAM_ARB) glLineWidth(OPENGL_PAINT_BOX+0.5) if is_delta: glLineStipple(1, 0xaaaa) glEnable(GL_LINE_STIPPLE) glBegin(GL_LINE_LOOP) color = BOX_COLORS.get(encoding, _DEFAULT_BOX_COLOR) log("Painting colored box around %s screen update using: %s (delta=%s)", encoding, color, is_delta) glColor4f(*color) for px,py in ((x, y), (x+w, y), (x+w, y+h), (x, y+h)): glVertex2i(px, py) glEnd() if is_delta: glDisable(GL_LINE_STIPPLE)
def _do_paint_rgb24(self, img_data, x, y, width, height, rowstride, options, callbacks): debug("%s._do_paint_rgb24(x=%d, y=%d, width=%d, height=%d, rowstride=%d)", self, x, y, width, height, rowstride) drawable = self.gl_init() if not drawable: debug("%s._do_paint_rgb24(..) drawable is not set!", self) return False try: self.set_rgb24_paint_state() # Compute alignment and row length row_length = 0 alignment = 1 for a in [2, 4, 8]: # Check if we are a-aligned - ! (var & 0x1) means 2-aligned or better, 0x3 - 4-aligned and so on if (rowstride & a-1) == 0: alignment = a # If number of extra bytes is greater than the alignment value, # then we also have to set row_length # Otherwise it remains at 0 (= width implicitely) if (rowstride - width * 3) > a: row_length = width + (rowstride - width * 3) / 3 self.gl_marker("RGB24 update at %d,%d, size %d,%d, stride is %d, row length %d, alignment %d" % (x, y, width, height, rowstride, row_length, alignment)) # Upload data as temporary RGB texture glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_RGB]) glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length) glPixelStorei(GL_UNPACK_ALIGNMENT, alignment) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data) # Draw textured RGB quad at the right coordinates glBegin(GL_QUADS) glTexCoord2i(0, 0) glVertex2i(x, y) glTexCoord2i(0, height) glVertex2i(x, y+height) glTexCoord2i(width, height) glVertex2i(x+width, y+height) glTexCoord2i(width, 0) glVertex2i(x+width, y) glEnd() # Present update to screen self.present_fbo(drawable) # present_fbo has reset state already finally: drawable.gl_end() return True
def present_fbo(self, drawable): self.gl_marker("Presenting FBO on screen for drawable %s" % drawable) assert drawable # Change state to target screen instead of our FBO glBindFramebuffer(GL_FRAMEBUFFER, 0) if self._has_alpha: # transparent background: glClearColor(0.0, 0.0, 0.0, 0.0) else: # plain white no alpha: glClearColor(1.0, 1.0, 1.0, 1.0) # Draw FBO texture on screen self.set_rgb_paint_state() glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_FBO]) if self._has_alpha: # support alpha channel if present: glEnable(GL_BLEND) glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD) glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO) w, h = self.size glBegin(GL_QUADS) glTexCoord2i(0, h) glVertex2i(0, 0) glTexCoord2i(0, 0) glVertex2i(0, h) glTexCoord2i(w, 0) glVertex2i(w, h) glTexCoord2i(w, h) glVertex2i(w, 0) glEnd() # Show the backbuffer on screen if drawable.is_double_buffered(): debug("%s.present_fbo() swapping buffers now", self) drawable.swap_buffers() # Clear the new backbuffer to illustrate that its contents are undefined glClear(GL_COLOR_BUFFER_BIT) else: glFlush() if self._has_alpha: glDisable(GL_BLEND) self.gl_frame_terminator() self.unset_rgb_paint_state() glBindFramebuffer(GL_FRAMEBUFFER, self.offscreen_fbo) debug("%s.present_fbo() done", self)
def _do_paint_rgb24(self, img_data, x, y, w, h, rowstride, options, callbacks): log("do_paint_rgb24(%s bytes, %s, %s, %s, %s, %s, %s, %s)", len(img_data), x, y, w, h, rowstride, options, callbacks) ww, wh = self.size if x + w > ww or y + h > wh: log("do_paint_rgb24: ignoring paint which would overflow the backing area" ) return drawable = self.gl_init() if not drawable: log("do_paint_rgb24: cannot paint yet..") return try: #cleanup if we were doing yuv previously: if self.pixel_format != GLPixmapBacking.RGB24: self.remove_shader() self.pixel_format = GLPixmapBacking.RGB24 glEnable(GL_TEXTURE_RECTANGLE_ARB) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[0]) glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstride / 3) for texture in (GL_TEXTURE1, GL_TEXTURE2): glActiveTexture(texture) glDisable(GL_TEXTURE_RECTANGLE_ARB) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, w, h, GL_RGB, GL_UNSIGNED_BYTE, img_data) glBegin(GL_QUADS) for rx, ry in ((x, y), (x, y + h), (x + w, y + h), (x + w, y)): glTexCoord2i(rx, ry) glVertex2i(rx, ry) glEnd() finally: self.gl_end(drawable)
def paint_rgb24(self, img_data, x, y, width, height, rowstride): # OpenGL begin if not self.gldrawable.gl_begin(self.glcontext): log.error("OUCH") return False # Upload texture if not self.texture: self.texture = glGenTextures(1) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.texture) glEnable(GL_TEXTURE_RECTANGLE_ARB) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstride / 3) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data) vtxarrays = 1 if vtxarrays == 1: texcoords = [[0, 0], [0, height], [width, height], [width, 0]] vtxcoords = texcoords glVertexPointeri(vtxcoords) glTexCoordPointeri(texcoords) glDrawArrays(GL_QUADS, 0, 4) else: glBegin(GL_QUADS) glTexCoord2i(0, 0) glVertex2i(0, 0) glTexCoord2i(0, height) glVertex2i(0, height) glTexCoord2i(width, height) glVertex2i(width, height) glTexCoord2i(width, 0) glVertex2i(width, 0) glEnd() # OpenGL end #self.gldrawable.swap_buffers() # self.gldrawable.swap_buffers() glFinish() self.gldrawable.gl_end()
def paint_rgb24(self, img_data, x, y, width, height, rowstride): # OpenGL begin if not self.gldrawable.gl_begin(self.glcontext): log.error("OUCH") return False # Upload texture if not self.texture: self.texture = glGenTextures(1) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.texture) glEnable(GL_TEXTURE_RECTANGLE_ARB) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstride/3) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data); vtxarrays=1 if vtxarrays == 1: texcoords = [ [ 0, 0 ], [ 0, height], [ width, height], [ width, 0] ] vtxcoords = texcoords glVertexPointeri(vtxcoords) glTexCoordPointeri(texcoords) glDrawArrays(GL_QUADS, 0, 4); else: glBegin(GL_QUADS); glTexCoord2i(0, 0); glVertex2i(0, 0); glTexCoord2i(0, height); glVertex2i(0, height); glTexCoord2i(width, height); glVertex2i(width, height); glTexCoord2i(width, 0); glVertex2i(width, 0); glEnd() # OpenGL end #self.gldrawable.swap_buffers() # self.gldrawable.swap_buffers() glFinish() self.gldrawable.gl_end()
def render_yuv_update(self, rx, ry, rw, rh): debug("render_yuv_update %sx%s at %sx%s pixel_format=%s", rw, rh, rx, ry, self.pixel_format) if self.pixel_format not in (YUV420P, YUV422P, YUV444P): #not ready to render yet return self.gl_marker("Painting YUV update") divs = get_subsampling_divs(self.pixel_format) glEnable(GL_FRAGMENT_PROGRAM_ARB) glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.yuv_shader[0]) for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)): glActiveTexture(texture) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index]) tw, th = self.texture_size debug("render_yuv_update texture_size=%s, size=%s", self.texture_size, self.size) glBegin(GL_QUADS) for x,y in ((rx, ry), (rx, ry+rh), (rx+rw, ry+rh), (rx+rw, ry)): ax = min(tw, x) ay = min(th, y) for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)): (div_w, div_h) = divs[index] glMultiTexCoord2i(texture, ax/div_w, ay/div_h) glVertex2i(ax, ay) glEnd()
def render(self): glClear(GL_COLOR_BUFFER_BIT) glBegin(GL_TRIANGLES) glColor3f(1.0, 0.0, 0.0) glVertex2i(0, 1) glColor3f(0.0, 1.0, 0.0) glVertex2i(-1, -1) glColor3f(0.0, 0.0, 1.0) glVertex2i(1, -1) glEnd()
def draw_triangle(): #print "Draw Triangle" glClearColor(0.0, 0.0, 0.0, 1.0) glClear(GL_COLOR_BUFFER_BIT) #return ### glBegin(GL_TRIANGLES) glColor3f(1.0, 0.0, 0.0) glVertex2i(0, 1) glColor3f(0.0, 1.0, 0.0) glVertex2i(-1, -1) glColor3f(0.0, 0.0, 1.0) glVertex2i(1, -1) glEnd()
def render_image(self): drawable = self.glarea.get_gl_drawable() context = self.glarea.get_gl_context() w, h = self.get_size() if not drawable.gl_begin(context): raise Exception("** Cannot create OpenGL rendering context!") texcoords = [ [ 0, 0 ], [ 0, h ], [ w, h ], [ w, 0 ] ] vtxcoords = texcoords if self.current_mode == GLClientWindow.MODE_RGB: glVertexPointeri(vtxcoords) glTexCoordPointeri(texcoords) glDrawArrays(GL_QUADS, 0, 4); elif self.current_mode == GLClientWindow.MODE_YUV: glEnable(GL_FRAGMENT_PROGRAM_ARB) glBegin(GL_QUADS); glMultiTexCoord2i(GL_TEXTURE0, 0, 0); glMultiTexCoord2i(GL_TEXTURE1, 0, 0); glMultiTexCoord2i(GL_TEXTURE2, 0, 0); glVertex2i(0, 0); glMultiTexCoord2i(GL_TEXTURE0, 0, h); glMultiTexCoord2i(GL_TEXTURE1, 0, h/2); glMultiTexCoord2i(GL_TEXTURE2, 0, h/2); glVertex2i(0, h); glMultiTexCoord2i(GL_TEXTURE0, w, h); glMultiTexCoord2i(GL_TEXTURE1, w/2, h/2); glMultiTexCoord2i(GL_TEXTURE2, w/2, h/2); glVertex2i(w, h); glMultiTexCoord2i(GL_TEXTURE0, w, 0); glMultiTexCoord2i(GL_TEXTURE1, w/2, 0); glMultiTexCoord2i(GL_TEXTURE2, w/2, 0); glVertex2i(w, 0); glEnd() drawable.swap_buffers() drawable.gl_end()
def draw_spinner(bw, bh): dim = min(bw / 3.0, bh / 3.0) t = monotonic_time() count = int(t * 4.0) bx = bw // 2 by = bh // 2 for i in range(8): #8 lines c = cv.trs[count % 8][i] mi1 = math.pi * i / 4 - math.pi / 16 mi2 = math.pi * i / 4 + math.pi / 16 si1 = math.sin(mi1) si2 = math.sin(mi2) ci1 = math.cos(mi1) ci2 = math.cos(mi2) glBegin(GL_POLYGON) glColor4f(c, c, c, 1) glVertex2i(int(bx + si1 * 10), int(by + ci1 * 10)) glVertex2i(int(bx + si1 * dim), int(by + ci1 * dim)) glVertex2i(int(bx + si2 * dim), int(by + ci2 * dim)) glVertex2i(int(bx + si2 * 10), int(by + ci2 * 10)) glEnd()
def present_fbo(self): drawable = self.gl_init() debug("present_fbo() drawable=%s", drawable) self.gl_marker("Presenting FBO on screen") if not drawable: return # Change state to target screen instead of our FBO glBindFramebuffer(GL_FRAMEBUFFER, 0) # Draw FBO texture on screen self.set_rgb24_paint_state() glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_FBO]) w, h = self.size glBegin(GL_QUADS) glTexCoord2i(0, h) glVertex2i(0, 0) glTexCoord2i(0, 0) glVertex2i(0, h) glTexCoord2i(w, 0) glVertex2i(w, h) glTexCoord2i(w, h) glVertex2i(w, 0) glEnd() # Show the backbuffer on screen if drawable.is_double_buffered(): debug("SWAPPING BUFFERS NOW") drawable.swap_buffers() # Clear the new backbuffer to illustrate that its contents are undefined glClear(GL_COLOR_BUFFER_BIT) else: glFlush() self.gl_frame_terminator() self.unset_rgb24_paint_state() glBindFramebuffer(GL_FRAMEBUFFER, self.offscreen_fbo) drawable.gl_end()
def render_image(self): drawable = self.glarea.get_gl_drawable() context = self.glarea.get_gl_context() w, h = self.get_size() if not drawable.gl_begin(context): raise Exception("** Cannot create OpenGL rendering context!") texcoords = [[0, 0], [0, h], [w, h], [w, 0]] vtxcoords = texcoords if self.current_mode == GLClientWindow.MODE_RGB: glVertexPointeri(vtxcoords) glTexCoordPointeri(texcoords) glDrawArrays(GL_QUADS, 0, 4) elif self.current_mode == GLClientWindow.MODE_YUV: glEnable(GL_FRAGMENT_PROGRAM_ARB) glBegin(GL_QUADS) glMultiTexCoord2i(GL_TEXTURE0, 0, 0) glMultiTexCoord2i(GL_TEXTURE1, 0, 0) glMultiTexCoord2i(GL_TEXTURE2, 0, 0) glVertex2i(0, 0) glMultiTexCoord2i(GL_TEXTURE0, 0, h) glMultiTexCoord2i(GL_TEXTURE1, 0, h / 2) glMultiTexCoord2i(GL_TEXTURE2, 0, h / 2) glVertex2i(0, h) glMultiTexCoord2i(GL_TEXTURE0, w, h) glMultiTexCoord2i(GL_TEXTURE1, w / 2, h / 2) glMultiTexCoord2i(GL_TEXTURE2, w / 2, h / 2) glVertex2i(w, h) glMultiTexCoord2i(GL_TEXTURE0, w, 0) glMultiTexCoord2i(GL_TEXTURE1, w / 2, 0) glMultiTexCoord2i(GL_TEXTURE2, w / 2, 0) glVertex2i(w, 0) glEnd() drawable.swap_buffers() drawable.gl_end()
def present_fbo(self, encoding, is_delta, x, y, w, h): if not self.paint_screen: return self.gl_marker("Presenting FBO on screen") # Change state to target screen instead of our FBO glBindFramebuffer(GL_FRAMEBUFFER, 0) if self._alpha_enabled: # transparent background: glClearColor(0.0, 0.0, 0.0, 0.0) else: # plain white no alpha: glClearColor(1.0, 1.0, 1.0, 1.0) # Draw FBO texture on screen self.set_rgb_paint_state() ww, wh = self.size if self.glconfig.is_double_buffered(): #refresh the whole window: x, y = 0, 0 w, h = ww, wh glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_FBO]) if self._alpha_enabled: # support alpha channel if present: glEnablei(GL_BLEND, self.textures[TEX_FBO]) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE) glBegin(GL_QUADS) #note how we invert coordinates.. glTexCoord2i(x, wh-y) glVertex2i(x, y) #top-left of window viewport glTexCoord2i(x, wh-y-h) glVertex2i(x, y+h) #bottom-left of window viewport glTexCoord2i(x+w, wh-y-h) glVertex2i(x+w, y+h) #bottom-right of window viewport glTexCoord2i(x+w, wh-y) glVertex2i(x+w, y) #top-right of window viewport glEnd() glDisable(GL_TEXTURE_RECTANGLE_ARB) #show region being painted: if OPENGL_PAINT_BOX: glLineWidth(1) if is_delta: glLineStipple(1, 0xf0f0) glEnable(GL_LINE_STIPPLE) glBegin(GL_LINE_LOOP) color = BOX_COLORS.get(encoding, _DEFAULT_BOX_COLOR) glColor4f(*color) for px,py in ((x, y), (x+w, y), (x+w, y+h), (x, y+h)): glVertex2i(px, py) glEnd() if is_delta: glDisable(GL_LINE_STIPPLE) if self.paint_spinner: #add spinner: dim = min(ww/3.0, wh/3.0) t = time.time() count = int(t*4.0) bx = ww//2 by = wh//2 for i in range(8): #8 lines glBegin(GL_POLYGON) c = cv.trs[count%8][i] glColor4f(c, c, c, 1) mi1 = math.pi*i/4-math.pi/16 mi2 = math.pi*i/4+math.pi/16 glVertex2i(int(bx+math.sin(mi1)*10), int(by+math.cos(mi1)*10)) glVertex2i(int(bx+math.sin(mi1)*dim), int(by+math.cos(mi1)*dim)) glVertex2i(int(bx+math.sin(mi2)*dim), int(by+math.cos(mi2)*dim)) glVertex2i(int(bx+math.sin(mi2)*10), int(by+math.cos(mi2)*10)) glEnd() #if desired, paint window border if self.border and self.border.shown: #double size since half the line will be off-screen glLineWidth(self.border.size*2) glBegin(GL_LINE_LOOP) glColor4f(self.border.red, self.border.green, self.border.blue, self.border.alpha) for px,py in ((0, 0), (ww, 0), (ww, wh), (0, wh)): glVertex2i(px, py) glEnd() # Show the backbuffer on screen self.gl_show() self.gl_frame_terminator() self.unset_rgb_paint_state() log("%s(%s, %s)", glBindFramebuffer, GL_FRAMEBUFFER, self.offscreen_fbo) glBindFramebuffer(GL_FRAMEBUFFER, self.offscreen_fbo) log("%s.present_fbo() done", self)
def draw_pointer(self): px, py, _, _, size, start_time = self.pointer_overlay elapsed = monotonic_time()-start_time log("pointer_overlay=%s, elapsed=%.1f, timeout=%s, cursor-data=%s", self.pointer_overlay, elapsed, CURSOR_IDLE_TIMEOUT, (self.cursor_data or [])[:7]) if elapsed>=CURSOR_IDLE_TIMEOUT: #timeout - stop showing it: self.pointer_overlay = None return x = px y = py if not self.cursor_data: #paint a fake one: alpha = max(0, (5.0-elapsed)/5.0) lw = 2 glLineWidth(lw) glBegin(GL_LINES) glColor4f(0, 0, 0, alpha) glVertex2i(x-size, y-lw//2) glVertex2i(x+size, y-lw//2) glVertex2i(x, y-size) glVertex2i(x, y+size) glEnd() return cw = self.cursor_data[3] ch = self.cursor_data[4] xhot = self.cursor_data[5] yhot = self.cursor_data[6] x = px-xhot y = py-yhot if TEXTURE_CURSOR: #paint the texture containing the cursor: glActiveTexture(GL_TEXTURE0) target = GL_TEXTURE_RECTANGLE_ARB glEnable(target) glBindTexture(target, self.textures[TEX_CURSOR]) glEnablei(GL_BLEND, self.textures[TEX_CURSOR]) glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA) glBlendFunc(GL_ONE, GL_ONE) glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE) glBegin(GL_QUADS) glTexCoord2i(0, 0) glVertex2i(x, y) glTexCoord2i(0, ch) glVertex2i(x, y+ch) glTexCoord2i(cw, ch) glVertex2i(x+cw, y+ch) glTexCoord2i(cw, 0) glVertex2i(x+cw, y) glEnd() glBindTexture(target, 0) glDisable(target) else: #FUGLY: paint each pixel separately.. if not self.validate_cursor(): return pixels = self.cursor_data[8] blen = cw*ch*4 p = struct.unpack(b"B"*blen, pixels) glLineWidth(1) #TODO: use VBO arrays to make this faster for cx in range(cw): for cy in range(ch): i = cx*4+cy*cw*4 if p[i+3]>=64: glBegin(GL_POINTS) glColor4f(p[i]/256.0, p[i+1]/256.0, p[i+2]/256.0, p[i+3]/256.0) glVertex2i(x+cx, y+cy) glEnd()
def present_fbo(self, drawable): if not self.paint_screen: return self.gl_marker("Presenting FBO on screen for drawable %s" % drawable) assert drawable # Change state to target screen instead of our FBO glBindFramebuffer(GL_FRAMEBUFFER, 0) if self._alpha_enabled: # transparent background: glClearColor(0.0, 0.0, 0.0, 0.0) else: # plain white no alpha: glClearColor(1.0, 1.0, 1.0, 1.0) # Draw FBO texture on screen self.set_rgb_paint_state() w, h = self.size glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_FBO]) if self._alpha_enabled: # support alpha channel if present: glEnablei(GL_BLEND, self.textures[TEX_FBO]) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glBegin(GL_QUADS) glTexCoord2i(0, h) glVertex2i(0, 0) glTexCoord2i(0, 0) glVertex2i(0, h) glTexCoord2i(w, 0) glVertex2i(w, h) glTexCoord2i(w, h) glVertex2i(w, 0) glEnd() #if desired, paint window border if self.border and self.border.shown: glDisable(GL_TEXTURE_RECTANGLE_ARB) #double size since half the line will be off-screen glLineWidth(self.border.size*2) glColor4f(self.border.red, self.border.green, self.border.blue, self.border.alpha) glBegin(GL_LINE_LOOP) for x,y in ((0, 0), (w, 0), (w, h), (0, h)): glVertex2i(x, y) glEnd() #reset color to default glColor4f(1.0, 1.0, 1.0, 1.0) # Show the backbuffer on screen if drawable.is_double_buffered(): log("%s.present_fbo() swapping buffers now", self) drawable.swap_buffers() # Clear the new backbuffer to illustrate that its contents are undefined glClear(GL_COLOR_BUFFER_BIT) else: glFlush() self.gl_frame_terminator() self.unset_rgb_paint_state() glBindFramebuffer(GL_FRAMEBUFFER, self.offscreen_fbo) log("%s.present_fbo() done", self)
def setPixel(xcoordinate, ycoordinate): glBegin(GL_POINTS) glVertex2i(xcoordinate, ycoordinate) glEnd() glFlush()
def do_present_fbo(self): self.gl_marker("Presenting FBO on screen") # Change state to target screen instead of our FBO glBindFramebuffer(GL_FRAMEBUFFER, 0) if self._alpha_enabled: # transparent background: glClearColor(0.0, 0.0, 0.0, 0.0) else: # plain white no alpha: glClearColor(1.0, 1.0, 1.0, 1.0) # Draw FBO texture on screen self.set_rgb_paint_state() bw, bh = self.size ww, wh = self.render_size if self.glconfig.is_double_buffered() or bw!=ww or bh!=wh: #refresh the whole window: rectangles = ((0, 0, bw, bh), ) else: #paint just the rectangles we have accumulated: rectangles = self.pending_fbo_paint self.pending_fbo_paint = [] log("do_present_fbo: painting %s", rectangles) glEnable(GL_TEXTURE_RECTANGLE_ARB) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_FBO]) if self._alpha_enabled: # support alpha channel if present: glEnablei(GL_BLEND, self.textures[TEX_FBO]) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE) #viewport for painting to window: glViewport(0, 0, ww, wh) if ww!=bw or wh!=bh: glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glBegin(GL_QUADS) for x,y,w,h in rectangles: #note how we invert coordinates.. tx1, ty1, tx2, ty2 = x, bh-y, x+w, bh-y-h vx1, vy1, vx2, vy2 = x, y, x+w, y+h glTexCoord2i(tx1, ty1) glVertex2i(vx1, vy1) #top-left of window viewport glTexCoord2i(tx1, ty2) glVertex2i(vx1, vy2) #bottom-left of window viewport glTexCoord2i(tx2, ty2) glVertex2i(vx2, vy2) #bottom-right of window viewport glTexCoord2i(tx2, ty1) glVertex2i(vx2, vy1) #top-right of window viewport glEnd() glDisable(GL_TEXTURE_RECTANGLE_ARB) if self.paint_spinner: #add spinner: dim = min(bw/3.0, bh/3.0) t = time.time() count = int(t*4.0) bx = bw//2 by = bh//2 for i in range(8): #8 lines glBegin(GL_POLYGON) c = cv.trs[count%8][i] glColor4f(c, c, c, 1) mi1 = math.pi*i/4-math.pi/16 mi2 = math.pi*i/4+math.pi/16 glVertex2i(int(bx+math.sin(mi1)*10), int(by+math.cos(mi1)*10)) glVertex2i(int(bx+math.sin(mi1)*dim), int(by+math.cos(mi1)*dim)) glVertex2i(int(bx+math.sin(mi2)*dim), int(by+math.cos(mi2)*dim)) glVertex2i(int(bx+math.sin(mi2)*10), int(by+math.cos(mi2)*10)) glEnd() #if desired, paint window border if self.border and self.border.shown: #double size since half the line will be off-screen glLineWidth(self.border.size*2) glBegin(GL_LINE_LOOP) glColor4f(self.border.red, self.border.green, self.border.blue, self.border.alpha) for px,py in ((0, 0), (bw, 0), (bw, bh), (0, bh)): glVertex2i(px, py) glEnd() # Show the backbuffer on screen self.gl_show() self.gl_frame_terminator() #restore pbo viewport glViewport(0, 0, bw, bh) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST) self.unset_rgb_paint_state() log("%s(%s, %s)", glBindFramebuffer, GL_FRAMEBUFFER, self.offscreen_fbo) glBindFramebuffer(GL_FRAMEBUFFER, self.offscreen_fbo) log("%s.do_present_fbo() done", self)
def paint_yuv420(self, img_data, x, y, width, height, rowstrides): #import time #before=time.time() # OpenGL begin if not self.gldrawable.gl_begin(self.glcontext): log.error("OUCH") return False # Upload texture if self.textures[0] == 0: self.textures = glGenTextures(3) glEnable(GL_FRAGMENT_PROGRAM_ARB) if not self.yuv420_shader: self.yuv420_shader = [ 1 ] glGenProgramsARB(1, self.yuv420_shader) glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.yuv420_shader[0]) # The following fragprog is: # * MIT X11 license, Copyright (c) 2007 by: # * Michael Dominic K. <*****@*****.**> #http://www.mdk.org.pl/2007/11/17/gl-colorspace-conversions prog = """!!ARBfp1.0 # cgc version 3.1.0010, build date Feb 10 2012 # command line args: -profile arbfp1 # source file: yuv.cg #vendor NVIDIA Corporation #version 3.1.0.10 #profile arbfp1 #program main #semantic main.IN #var float2 IN.texcoord1 : $vin.TEXCOORD0 : TEX0 : 0 : 1 #var float2 IN.texcoord2 : $vin.TEXCOORD1 : TEX1 : 0 : 1 #var float2 IN.texcoord3 : $vin.TEXCOORD2 : TEX2 : 0 : 1 #var samplerRECT IN.texture1 : TEXUNIT0 : texunit 0 : 0 : 1 #var samplerRECT IN.texture2 : TEXUNIT1 : texunit 1 : 0 : 1 #var samplerRECT IN.texture3 : TEXUNIT2 : texunit 2 : 0 : 1 #var float4 IN.color : $vin.COLOR0 : COL0 : 0 : 1 #var float4 main.color : $vout.COLOR0 : COL : -1 : 1 #const c[0] = 1.1643835 2.017231 0 0.5 #const c[1] = 0.0625 1.1643835 -0.3917616 -0.81296802 #const c[2] = 1.1643835 0 1.5960271 PARAM c[3] = { { 1.1643835, 2.017231, 0, 0.5 }, { 0.0625, 1.1643835, -0.3917616, -0.81296802 }, { 1.1643835, 0, 1.5960271 } }; TEMP R0; TEMP R1; TEX R0.x, fragment.texcoord[2], texture[2], RECT; ADD R1.z, R0.x, -c[0].w; TEX R1.x, fragment.texcoord[0], texture[0], RECT; TEX R0.x, fragment.texcoord[1], texture[1], RECT; ADD R1.x, R1, -c[1]; ADD R1.y, R0.x, -c[0].w; DP3 result.color.z, R1, c[0]; DP3 result.color.y, R1, c[1].yzww; DP3 result.color.x, R1, c[2]; MOV result.color.w, fragment.color.primary; END # 10 instructions, 2 R-regs """ glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, len(prog), prog) log.error(glGetString(GL_PROGRAM_ERROR_STRING_ARB)) glEnable(GL_FRAGMENT_PROGRAM_ARB) glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.yuv420_shader[0]) glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[0]) glEnable(GL_TEXTURE_RECTANGLE_ARB) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[0]) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, img_data[0]); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[1]) glEnable(GL_TEXTURE_RECTANGLE_ARB) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[1]) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, width/2, height/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, img_data[1]); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[2]) glEnable(GL_TEXTURE_RECTANGLE_ARB) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[2]) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, width/2, height/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, img_data[2]); vtxarrays=0 if vtxarrays == 1: texcoords = [ [ 0, 0 ], [ 0, height], [ width, height], [ width, 0] ] vtxcoords = texcoords texcoords_half = [ [ 0, 0 ], [ 0, height/2], [ width/2, height/2], [ width/2, 0] ] glVertexPointeri(vtxcoords) glActiveTexture(GL_TEXTURE0); glClientActiveTexture(GL_TEXTURE0) glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointeri(texcoords) glActiveTexture(GL_TEXTURE1); glClientActiveTexture(GL_TEXTURE1) glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointeri(texcoords_half) glActiveTexture(GL_TEXTURE2); glClientActiveTexture(GL_TEXTURE2) glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointeri(texcoords_half) glDrawArrays(GL_QUADS, 0, 4); else: glBegin(GL_QUADS); glMultiTexCoord2i(GL_TEXTURE0, 0, 0); glMultiTexCoord2i(GL_TEXTURE1, 0, 0); glMultiTexCoord2i(GL_TEXTURE2, 0, 0); glVertex2i(0, 0); glMultiTexCoord2i(GL_TEXTURE0, 0, height); glMultiTexCoord2i(GL_TEXTURE1, 0, height/2); glMultiTexCoord2i(GL_TEXTURE2, 0, height/2); glVertex2i(0, height); glMultiTexCoord2i(GL_TEXTURE0, width, height); glMultiTexCoord2i(GL_TEXTURE1, width/2, height/2); glMultiTexCoord2i(GL_TEXTURE2, width/2, height/2); glVertex2i(width, height); glMultiTexCoord2i(GL_TEXTURE0, width, 0); glMultiTexCoord2i(GL_TEXTURE1, width/2, 0); glMultiTexCoord2i(GL_TEXTURE2, width/2, 0); glVertex2i(width, 0); glEnd() # OpenGL end #self.gldrawable.swap_buffers() # self.gldrawable.swap_buffers() glFinish() self.gldrawable.gl_end()
def _do_paint_rgb(self, bpp, img_data, x, y, width, height, rowstride, options): log("%s._do_paint_rgb(%s, %s bytes, x=%d, y=%d, width=%d, height=%d, rowstride=%d, options=%s)", self, bpp, len(img_data), x, y, width, height, rowstride, options) context = self.gl_context() if not context: log("%s._do_paint_rgb(..) no context!", self) return False #TODO: move this code up to the decode thread section upload, img_data = self.pixels_for_upload(img_data) with context: self.gl_init() self.set_rgb_paint_state() rgb_format = options.get(b"rgb_format") if not rgb_format: #Older servers may not tell us the pixel format, so we must infer it: if bpp==24: rgb_format = "RGB" else: assert bpp==32 rgb_format = "RGBA" else: rgb_format = rgb_format.decode() #convert it to a GL constant: pformat = PIXEL_FORMAT_TO_CONSTANT.get(rgb_format) assert pformat is not None, "could not find pixel format for %s (bpp=%s)" % (rgb_format, bpp) bytes_per_pixel = len(rgb_format) #ie: BGRX -> 4 # Compute alignment and row length row_length = 0 alignment = 1 for a in [2, 4, 8]: # Check if we are a-aligned - ! (var & 0x1) means 2-aligned or better, 0x3 - 4-aligned and so on if (rowstride & a-1) == 0: alignment = a # If number of extra bytes is greater than the alignment value, # then we also have to set row_length # Otherwise it remains at 0 (= width implicitely) if (rowstride - width * bytes_per_pixel) >= alignment: row_length = width + (rowstride - width * bytes_per_pixel) // bytes_per_pixel self.gl_marker("%s %sbpp update at (%d,%d) size %dx%d (%s bytes), stride=%d, row length %d, alignment %d, using GL %s format=%s", rgb_format, bpp, x, y, width, height, len(img_data), rowstride, row_length, alignment, upload, CONSTANT_TO_PIXEL_FORMAT.get(pformat)) # Upload data as temporary RGB texture glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_RGB]) glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length) glPixelStorei(GL_UNPACK_ALIGNMENT, alignment) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_BASE_LEVEL, 0) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAX_LEVEL, 0) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, self.texture_pixel_format, width, height, 0, pformat, GL_UNSIGNED_BYTE, img_data) # Draw textured RGB quad at the right coordinates glBegin(GL_QUADS) glTexCoord2i(0, 0) glVertex2i(x, y) glTexCoord2i(0, height) glVertex2i(x, y+height) glTexCoord2i(width, height) glVertex2i(x+width, y+height) glTexCoord2i(width, 0) glVertex2i(x+width, y) glEnd() self.paint_box(options.get("encoding"), options.get("delta", -1)>=0, x, y, width, height) # Present update to screen self.present_fbo(x, y, width, height, options.get("flush", 0)) # present_fbo has reset state already return True
def present_fbo(self, encoding, is_delta, x, y, w, h): if not self.paint_screen: return self.gl_marker("Presenting FBO on screen") # Change state to target screen instead of our FBO glBindFramebuffer(GL_FRAMEBUFFER, 0) if self._alpha_enabled: # transparent background: glClearColor(0.0, 0.0, 0.0, 0.0) else: # plain white no alpha: glClearColor(1.0, 1.0, 1.0, 1.0) # Draw FBO texture on screen self.set_rgb_paint_state() ww, wh = self.size if self.glconfig.is_double_buffered(): #refresh the whole window: x, y = 0, 0 w, h = ww, wh glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_FBO]) if self._alpha_enabled: # support alpha channel if present: glEnablei(GL_BLEND, self.textures[TEX_FBO]) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE) glBegin(GL_QUADS) #note how we invert coordinates.. glTexCoord2i(x, wh - y) glVertex2i(x, y) #top-left of window viewport glTexCoord2i(x, wh - y - h) glVertex2i(x, y + h) #bottom-left of window viewport glTexCoord2i(x + w, wh - y - h) glVertex2i(x + w, y + h) #bottom-right of window viewport glTexCoord2i(x + w, wh - y) glVertex2i(x + w, y) #top-right of window viewport glEnd() glDisable(GL_TEXTURE_RECTANGLE_ARB) #show region being painted: if OPENGL_PAINT_BOX: glLineWidth(1) if is_delta: glLineStipple(1, 0xf0f0) glEnable(GL_LINE_STIPPLE) glBegin(GL_LINE_LOOP) color = BOX_COLORS.get(encoding, _DEFAULT_BOX_COLOR) glColor4f(*color) for px, py in ((x, y), (x + w, y), (x + w, y + h), (x, y + h)): glVertex2i(px, py) glEnd() if is_delta: glDisable(GL_LINE_STIPPLE) if self.paint_spinner: #add spinner: dim = min(ww / 3.0, wh / 3.0) t = time.time() count = int(t * 4.0) bx = ww // 2 by = wh // 2 for i in range(8): #8 lines glBegin(GL_POLYGON) c = cv.trs[count % 8][i] glColor4f(c, c, c, 1) mi1 = math.pi * i / 4 - math.pi / 16 mi2 = math.pi * i / 4 + math.pi / 16 glVertex2i(int(bx + math.sin(mi1) * 10), int(by + math.cos(mi1) * 10)) glVertex2i(int(bx + math.sin(mi1) * dim), int(by + math.cos(mi1) * dim)) glVertex2i(int(bx + math.sin(mi2) * dim), int(by + math.cos(mi2) * dim)) glVertex2i(int(bx + math.sin(mi2) * 10), int(by + math.cos(mi2) * 10)) glEnd() #if desired, paint window border if self.border and self.border.shown: #double size since half the line will be off-screen glLineWidth(self.border.size * 2) glBegin(GL_LINE_LOOP) glColor4f(self.border.red, self.border.green, self.border.blue, self.border.alpha) for px, py in ((0, 0), (ww, 0), (ww, wh), (0, wh)): glVertex2i(px, py) glEnd() # Show the backbuffer on screen self.gl_show() self.gl_frame_terminator() self.unset_rgb_paint_state() log("%s(%s, %s)", glBindFramebuffer, GL_FRAMEBUFFER, self.offscreen_fbo) glBindFramebuffer(GL_FRAMEBUFFER, self.offscreen_fbo) log("%s.present_fbo() done", self)
def do_paint_rgb(self, rgb_format, img_data, x, y, width, height, rowstride, options, callbacks): log( "%s.do_paint_rgb(%s, %s bytes, x=%d, y=%d, width=%d, height=%d, rowstride=%d, options=%s)", self, rgb_format, len(img_data), x, y, width, height, rowstride, options) context = self.gl_context() if not context: log("%s._do_paint_rgb(..) no context!", self) fire_paint_callbacks(callbacks, False, "no opengl context") return if not options.get("paint", True): fire_paint_callbacks(callbacks) return try: upload, img_data = self.pixels_for_upload(img_data) with context: self.gl_init() self.set_rgb_paint_state() #convert it to a GL constant: pformat = PIXEL_FORMAT_TO_CONSTANT.get(rgb_format.decode()) assert pformat is not None, "could not find pixel format for %s" % rgb_format bytes_per_pixel = len(rgb_format) #ie: BGRX -> 4 # Compute alignment and row length row_length = 0 alignment = 1 for a in [2, 4, 8]: # Check if we are a-aligned - ! (var & 0x1) means 2-aligned or better, 0x3 - 4-aligned and so on if (rowstride & a - 1) == 0: alignment = a # If number of extra bytes is greater than the alignment value, # then we also have to set row_length # Otherwise it remains at 0 (= width implicitely) if (rowstride - width * bytes_per_pixel) >= alignment: row_length = width + ( rowstride - width * bytes_per_pixel) // bytes_per_pixel self.gl_marker( "%s update at (%d,%d) size %dx%d (%s bytes), stride=%d, row length %d, alignment %d, using GL %s format=%s", rgb_format, x, y, width, height, len(img_data), rowstride, row_length, alignment, upload, CONSTANT_TO_PIXEL_FORMAT.get(pformat)) # Upload data as temporary RGB texture glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_RGB]) glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length) glPixelStorei(GL_UNPACK_ALIGNMENT, alignment) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST) set_texture_level() glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, self.texture_pixel_format, width, height, 0, pformat, GL_UNSIGNED_BYTE, img_data) # Draw textured RGB quad at the right coordinates glBegin(GL_QUADS) glTexCoord2i(0, 0) glVertex2i(x, y) glTexCoord2i(0, height) glVertex2i(x, y + height) glTexCoord2i(width, height) glVertex2i(x + width, y + height) glTexCoord2i(width, 0) glVertex2i(x + width, y) glEnd() self.paint_box(options.get("encoding"), options.get("delta", -1) >= 0, x, y, width, height) # Present update to screen self.present_fbo(x, y, width, height, options.get("flush", 0)) # present_fbo has reset state already fire_paint_callbacks(callbacks) except Exception as e: log("Error in %s paint of %i bytes, options=%s)", rgb_format, len(img_data), options) fire_paint_callbacks(callbacks, False, "opengl %s paint error: %s" % (rgb_format, e))
def do_present_fbo(self): bw, bh = self.size ww, wh = self.render_size self.gl_marker("Presenting FBO on screen") # Change state to target screen instead of our FBO glBindFramebuffer(GL_FRAMEBUFFER, 0) glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0) left, top, right, bottom = self.offsets #viewport for clearing the whole window: glViewport(0, 0, left+ww+right, top+wh+bottom) if self._alpha_enabled: # transparent background: glClearColor(0.0, 0.0, 0.0, 0.0) else: # black, no alpha: glClearColor(0.0, 0.0, 0.0, 1.0) if left or top or right or bottom: try: glClear(GL_COLOR_BUFFER_BIT) except: log("ignoring glClear(GL_COLOR_BUFFER_BIT) error, buggy driver?", exc_info=True) #viewport for painting to window: glViewport(left, top, ww, wh) # Draw FBO texture on screen self.set_rgb_paint_state() rect_count = len(self.pending_fbo_paint) if self.glconfig.is_double_buffered() or bw!=ww or bh!=wh: #refresh the whole window: rectangles = ((0, 0, bw, bh), ) else: #paint just the rectangles we have accumulated: rectangles = self.pending_fbo_paint self.pending_fbo_paint = [] log("do_present_fbo: painting %s", rectangles) glEnable(GL_TEXTURE_RECTANGLE_ARB) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_FBO]) if self._alpha_enabled: # support alpha channel if present: glEnablei(GL_BLEND, self.textures[TEX_FBO]) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE) if SAVE_BUFFERS: glBindFramebuffer(GL_READ_FRAMEBUFFER, self.offscreen_fbo) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_FBO]) glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_FBO], 0) glReadBuffer(GL_COLOR_ATTACHMENT0) glViewport(0, 0, bw, bh) from OpenGL.GL import glGetTexImage size = bw*bh*4 import numpy data = numpy.empty(size) img_data = glGetTexImage(GL_TEXTURE_RECTANGLE_ARB, 0, GL_BGRA, GL_UNSIGNED_BYTE, data) from PIL import Image, ImageOps img = Image.frombuffer("RGBA", (bw, bh), img_data, "raw", "BGRA", bw*4) img = ImageOps.flip(img) kwargs = {} if SAVE_BUFFERS=="jpeg": kwargs = { "quality" : 0, "optimize" : False, } t = time.time() tstr = time.strftime("%H-%M-%S", time.localtime(t)) filename = "./W%i-FBO-%s.%03i.%s" % (self.wid, tstr, (t*1000)%1000, SAVE_BUFFERS) log("do_present_fbo: saving %4ix%-4i pixels, %7i bytes to %s", bw, bh, size, filename) img.save(filename, SAVE_BUFFERS, **kwargs) glBindFramebuffer(GL_READ_FRAMEBUFFER, 0) if ww!=bw or wh!=bh: glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glBegin(GL_QUADS) for x,y,w,h in rectangles: #note how we invert coordinates.. tx1, ty1, tx2, ty2 = x, bh-y, x+w, bh-y-h vx1, vy1, vx2, vy2 = x, y, x+w, y+h glTexCoord2i(tx1, ty1) glVertex2i(vx1, vy1) #top-left of window viewport glTexCoord2i(tx1, ty2) glVertex2i(vx1, vy2) #bottom-left of window viewport glTexCoord2i(tx2, ty2) glVertex2i(vx2, vy2) #bottom-right of window viewport glTexCoord2i(tx2, ty1) glVertex2i(vx2, vy1) #top-right of window viewport glEnd() glDisable(GL_TEXTURE_RECTANGLE_ARB) if self.paint_spinner: #add spinner: dim = min(bw/3.0, bh/3.0) t = time.time() count = int(t*4.0) bx = bw//2 by = bh//2 for i in range(8): #8 lines glBegin(GL_POLYGON) c = cv.trs[count%8][i] glColor4f(c, c, c, 1) mi1 = math.pi*i/4-math.pi/16 mi2 = math.pi*i/4+math.pi/16 glVertex2i(int(bx+math.sin(mi1)*10), int(by+math.cos(mi1)*10)) glVertex2i(int(bx+math.sin(mi1)*dim), int(by+math.cos(mi1)*dim)) glVertex2i(int(bx+math.sin(mi2)*dim), int(by+math.cos(mi2)*dim)) glVertex2i(int(bx+math.sin(mi2)*10), int(by+math.cos(mi2)*10)) glEnd() #if desired, paint window border if self.border and self.border.shown: #double size since half the line will be off-screen glLineWidth(self.border.size*2) glBegin(GL_LINE_LOOP) glColor4f(self.border.red, self.border.green, self.border.blue, self.border.alpha) for px,py in ((0, 0), (bw, 0), (bw, bh), (0, bh)): glVertex2i(px, py) glEnd() if self.pointer_overlay: x, y, _, _, size, start_time = self.pointer_overlay elapsed = time.time()-start_time if elapsed<6: alpha = max(0, (5.0-elapsed)/5.0) glLineWidth(1) glBegin(GL_LINES) glColor4f(0, 0, 0, alpha) glVertex2i(x-size, y) glVertex2i(x+size, y) glVertex2i(x, y-size) glVertex2i(x, y+size) glEnd() else: self.pointer_overlay = None # Show the backbuffer on screen self.gl_show(rect_count) self.gl_frame_terminator() #restore pbo viewport glViewport(0, 0, bw, bh) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST) self.unset_rgb_paint_state() log("%s(%s, %s)", glBindFramebuffer, GL_FRAMEBUFFER, self.offscreen_fbo) glBindFramebuffer(GL_FRAMEBUFFER, self.offscreen_fbo) log("%s.do_present_fbo() done", self)
def present_fbo(self, drawable): if not self.paint_screen: return self.gl_marker("Presenting FBO on screen for drawable %s" % drawable) assert drawable # Change state to target screen instead of our FBO glBindFramebuffer(GL_FRAMEBUFFER, 0) if self._alpha_enabled: # transparent background: glClearColor(0.0, 0.0, 0.0, 0.0) else: # plain white no alpha: glClearColor(1.0, 1.0, 1.0, 1.0) # Draw FBO texture on screen self.set_rgb_paint_state() w, h = self.size glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_FBO]) if self._alpha_enabled: # support alpha channel if present: glEnablei(GL_BLEND, self.textures[TEX_FBO]) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glBegin(GL_QUADS) glTexCoord2i(0, h) glVertex2i(0, 0) glTexCoord2i(0, 0) glVertex2i(0, h) glTexCoord2i(w, 0) glVertex2i(w, h) glTexCoord2i(w, h) glVertex2i(w, 0) glEnd() #if desired, paint window border if self.border and self.border.shown: glDisable(GL_TEXTURE_RECTANGLE_ARB) #double size since half the line will be off-screen glLineWidth(self.border.size * 2) glColor4f(self.border.red, self.border.green, self.border.blue, self.border.alpha) glBegin(GL_LINE_LOOP) for x, y in ((0, 0), (w, 0), (w, h), (0, h)): glVertex2i(x, y) glEnd() #reset color to default glColor4f(1.0, 1.0, 1.0, 1.0) # Show the backbuffer on screen if drawable.is_double_buffered(): log("%s.present_fbo() swapping buffers now", self) drawable.swap_buffers() # Clear the new backbuffer to illustrate that its contents are undefined glClear(GL_COLOR_BUFFER_BIT) else: glFlush() self.gl_frame_terminator() self.unset_rgb_paint_state() glBindFramebuffer(GL_FRAMEBUFFER, self.offscreen_fbo) log("%s.present_fbo() done", self)
def _do_paint_rgb(self, bpp, img_data, x, y, width, height, rowstride, options): log( "%s._do_paint_rgb(%s, %s bytes, x=%d, y=%d, width=%d, height=%d, rowstride=%d)", self, bpp, len(img_data), x, y, width, height, rowstride) drawable = self.gl_init() if not drawable: log("%s._do_paint_rgb(..) drawable is not set!", self) return False #deal with buffers uploads by wrapping them if we can, or copy to a string: if type(img_data) == buffer: if memoryview_type is not None: img_data = memoryview_type(img_data) else: img_data = str(img_data) try: self.set_rgb_paint_state() rgb_format = options.get("rgb_format") if not rgb_format: #Older servers may not tell us the pixel format, so we must infer it: if bpp == 24: rgb_format = "RGB" else: assert bpp == 32 rgb_format = "RGBA" #convert it to a GL constant: pformat = PIXEL_FORMAT_TO_CONSTANT.get(rgb_format) assert pformat is not None, "could not find pixel format for %s (bpp=%s)" % ( rgb_format, bpp) bytes_per_pixel = len(rgb_format) #ie: BGRX -> 4 # Compute alignment and row length row_length = 0 alignment = 1 for a in [2, 4, 8]: # Check if we are a-aligned - ! (var & 0x1) means 2-aligned or better, 0x3 - 4-aligned and so on if (rowstride & a - 1) == 0: alignment = a # If number of extra bytes is greater than the alignment value, # then we also have to set row_length # Otherwise it remains at 0 (= width implicitely) if (rowstride - width * bytes_per_pixel) >= alignment: row_length = width + ( rowstride - width * bytes_per_pixel) / bytes_per_pixel self.gl_marker( "%s %sbpp update at (%d,%d) size %dx%d (%s bytes), stride=%d, row length %d, alignment %d, using GL upload format=%s" % (rgb_format, bpp, x, y, width, height, len(img_data), rowstride, row_length, alignment, CONSTANT_TO_PIXEL_FORMAT.get(pformat))) # Upload data as temporary RGB texture glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_RGB]) glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length) glPixelStorei(GL_UNPACK_ALIGNMENT, alignment) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, self.texture_pixel_format, width, height, 0, pformat, GL_UNSIGNED_BYTE, img_data) # Draw textured RGB quad at the right coordinates glBegin(GL_QUADS) glTexCoord2i(0, 0) glVertex2i(x, y) glTexCoord2i(0, height) glVertex2i(x, y + height) glTexCoord2i(width, height) glVertex2i(x + width, y + height) glTexCoord2i(width, 0) glVertex2i(x + width, y) glEnd() # Present update to screen self.present_fbo(drawable) # present_fbo has reset state already finally: drawable.gl_end() return True
def do_paint_rgb(self, rgb_format, img_data, x, y, width, height, rowstride, options, callbacks): log("%s.do_paint_rgb(%s, %s bytes, x=%d, y=%d, width=%d, height=%d, rowstride=%d, options=%s)", self, rgb_format, len(img_data), x, y, width, height, rowstride, options) context = self.gl_context() if not context: log("%s._do_paint_rgb(..) no context!", self) fire_paint_callbacks(callbacks, False, "no opengl context") return if not options.get("paint", True): fire_paint_callbacks(callbacks) return try: upload, img_data = self.pixels_for_upload(img_data) with context: self.gl_init() self.set_rgb_paint_state() #convert it to a GL constant: pformat = PIXEL_FORMAT_TO_CONSTANT.get(rgb_format.decode()) assert pformat is not None, "could not find pixel format for %s" % rgb_format bytes_per_pixel = len(rgb_format) #ie: BGRX -> 4 # Compute alignment and row length row_length = 0 alignment = 1 for a in [2, 4, 8]: # Check if we are a-aligned - ! (var & 0x1) means 2-aligned or better, 0x3 - 4-aligned and so on if (rowstride & a-1) == 0: alignment = a # If number of extra bytes is greater than the alignment value, # then we also have to set row_length # Otherwise it remains at 0 (= width implicitely) if (rowstride - width * bytes_per_pixel) >= alignment: row_length = width + (rowstride - width * bytes_per_pixel) // bytes_per_pixel self.gl_marker("%s update at (%d,%d) size %dx%d (%s bytes), stride=%d, row length %d, alignment %d, using GL %s format=%s", rgb_format, x, y, width, height, len(img_data), rowstride, row_length, alignment, upload, CONSTANT_TO_PIXEL_FORMAT.get(pformat)) # Upload data as temporary RGB texture glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_RGB]) glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length) glPixelStorei(GL_UNPACK_ALIGNMENT, alignment) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST) set_texture_level() glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, self.texture_pixel_format, width, height, 0, pformat, GL_UNSIGNED_BYTE, img_data) # Draw textured RGB quad at the right coordinates glBegin(GL_QUADS) glTexCoord2i(0, 0) glVertex2i(x, y) glTexCoord2i(0, height) glVertex2i(x, y+height) glTexCoord2i(width, height) glVertex2i(x+width, y+height) glTexCoord2i(width, 0) glVertex2i(x+width, y) glEnd() self.paint_box(options.get("encoding"), options.get("delta", -1)>=0, x, y, width, height) # Present update to screen self.present_fbo(x, y, width, height, options.get("flush", 0)) # present_fbo has reset state already fire_paint_callbacks(callbacks) except Exception as e: log("Error in %s paint of %i bytes, options=%s)", rgb_format, len(img_data), options) fire_paint_callbacks(callbacks, False, "OpenGL %s paint error: %s" % (rgb_format, e))
def _do_paint_rgb(self, bpp, img_data, x, y, width, height, rowstride, options, callbacks): debug( "%s._do_paint_rgb(%s, %s bytes, x=%d, y=%d, width=%d, height=%d, rowstride=%d)", self, bpp, len(img_data), x, y, width, height, rowstride, ) drawable = self.gl_init() if not drawable: debug("%s._do_paint_rgb(..) drawable is not set!", self) return False try: self.set_rgb_paint_state() bytes_per_pixel = bpp / 8 # Compute alignment and row length row_length = 0 alignment = 1 for a in [2, 4, 8]: # Check if we are a-aligned - ! (var & 0x1) means 2-aligned or better, 0x3 - 4-aligned and so on if (rowstride & a - 1) == 0: alignment = a # If number of extra bytes is greater than the alignment value, # then we also have to set row_length # Otherwise it remains at 0 (= width implicitely) if (rowstride - width * bytes_per_pixel) > a: row_length = width + (rowstride - width * bytes_per_pixel) / bytes_per_pixel rgb_format = options.get("rgb_format", None) self.gl_marker( "%s %sbpp update at %d,%d, size %d,%d, stride is %d, row length %d, alignment %d" % (rgb_format, bpp, x, y, width, height, rowstride, row_length, alignment) ) # Upload data as temporary RGB texture if bpp == 24: if rgb_format == "BGR": pformat = GL_BGR else: assert rgb_format in ("RGB", None), "invalid 24-bit format: %s" % rgb_format pformat = GL_RGB else: assert bpp == 32 if rgb_format == "BGRA": pformat = GL_BGRA else: assert rgb_format in ("RGBA", None), "invalid 32-bit format: %s" % rgb_format pformat = GL_RGBA glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_RGB]) glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length) glPixelStorei(GL_UNPACK_ALIGNMENT, alignment) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, 0, pformat, GL_UNSIGNED_BYTE, img_data) # Draw textured RGB quad at the right coordinates glBegin(GL_QUADS) glTexCoord2i(0, 0) glVertex2i(x, y) glTexCoord2i(0, height) glVertex2i(x, y + height) glTexCoord2i(width, height) glVertex2i(x + width, y + height) glTexCoord2i(width, 0) glVertex2i(x + width, y) glEnd() # Present update to screen self.present_fbo(drawable) # present_fbo has reset state already finally: drawable.gl_end() return True
def do_present_fbo(self): bw, bh = self.size ww, wh = self.render_size self.gl_marker("Presenting FBO on screen") # Change state to target screen instead of our FBO glBindFramebuffer(GL_FRAMEBUFFER, 0) glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0) if self._alpha_enabled: # transparent background: glClearColor(0.0, 0.0, 0.0, 0.0) else: # plain white no alpha: glClearColor(1.0, 1.0, 1.0, 1.0) # Draw FBO texture on screen self.set_rgb_paint_state() rect_count = len(self.pending_fbo_paint) if self.glconfig.is_double_buffered() or bw!=ww or bh!=wh: #refresh the whole window: rectangles = ((0, 0, bw, bh), ) else: #paint just the rectangles we have accumulated: rectangles = self.pending_fbo_paint self.pending_fbo_paint = [] log("do_present_fbo: painting %s", rectangles) glEnable(GL_TEXTURE_RECTANGLE_ARB) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_FBO]) if self._alpha_enabled: # support alpha channel if present: glEnablei(GL_BLEND, self.textures[TEX_FBO]) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE) if SAVE_BUFFERS: glBindFramebuffer(GL_READ_FRAMEBUFFER, self.offscreen_fbo) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_FBO]) glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_FBO], 0) glReadBuffer(GL_COLOR_ATTACHMENT0) glViewport(0, 0, bw, bh) from OpenGL.GL import glGetTexImage size = bw*bh*4 import numpy data = numpy.empty(size) img_data = glGetTexImage(GL_TEXTURE_RECTANGLE_ARB, 0, GL_BGRA, GL_UNSIGNED_BYTE, data) from PIL import Image, ImageOps img = Image.frombuffer("RGBA", (bw, bh), img_data, "raw", "BGRA", bw*4) img = ImageOps.flip(img) kwargs = {} if SAVE_BUFFERS=="jpeg": kwargs = { "quality" : 0, "optimize" : False, } t = time.time() tstr = time.strftime("%H-%M-%S", time.localtime(t)) filename = "./W%i-FBO-%s.%03i.%s" % (self.wid, tstr, (t*1000)%1000, SAVE_BUFFERS) log("do_present_fbo: saving %4ix%-4i pixels, %7i bytes to %s", bw, bh, size, filename) img.save(filename, SAVE_BUFFERS, **kwargs) glBindFramebuffer(GL_READ_FRAMEBUFFER, 0) #viewport for painting to window: glViewport(0, 0, ww, wh) if ww!=bw or wh!=bh: glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glBegin(GL_QUADS) for x,y,w,h in rectangles: #note how we invert coordinates.. tx1, ty1, tx2, ty2 = x, bh-y, x+w, bh-y-h vx1, vy1, vx2, vy2 = x, y, x+w, y+h glTexCoord2i(tx1, ty1) glVertex2i(vx1, vy1) #top-left of window viewport glTexCoord2i(tx1, ty2) glVertex2i(vx1, vy2) #bottom-left of window viewport glTexCoord2i(tx2, ty2) glVertex2i(vx2, vy2) #bottom-right of window viewport glTexCoord2i(tx2, ty1) glVertex2i(vx2, vy1) #top-right of window viewport glEnd() glDisable(GL_TEXTURE_RECTANGLE_ARB) if self.paint_spinner: #add spinner: dim = min(bw/3.0, bh/3.0) t = time.time() count = int(t*4.0) bx = bw//2 by = bh//2 for i in range(8): #8 lines glBegin(GL_POLYGON) c = cv.trs[count%8][i] glColor4f(c, c, c, 1) mi1 = math.pi*i/4-math.pi/16 mi2 = math.pi*i/4+math.pi/16 glVertex2i(int(bx+math.sin(mi1)*10), int(by+math.cos(mi1)*10)) glVertex2i(int(bx+math.sin(mi1)*dim), int(by+math.cos(mi1)*dim)) glVertex2i(int(bx+math.sin(mi2)*dim), int(by+math.cos(mi2)*dim)) glVertex2i(int(bx+math.sin(mi2)*10), int(by+math.cos(mi2)*10)) glEnd() #if desired, paint window border if self.border and self.border.shown: #double size since half the line will be off-screen glLineWidth(self.border.size*2) glBegin(GL_LINE_LOOP) glColor4f(self.border.red, self.border.green, self.border.blue, self.border.alpha) for px,py in ((0, 0), (bw, 0), (bw, bh), (0, bh)): glVertex2i(px, py) glEnd() if self.pointer_overlay: x, y, _, _, size, start_time = self.pointer_overlay elapsed = time.time()-start_time if elapsed<6: alpha = max(0, (5.0-elapsed)/5.0) glLineWidth(1) glBegin(GL_LINES) glColor4f(0, 0, 0, alpha) glVertex2i(x-size, y) glVertex2i(x+size, y) glVertex2i(x, y-size) glVertex2i(x, y+size) glEnd() else: self.pointer_overlay = None # Show the backbuffer on screen self.gl_show(rect_count) self.gl_frame_terminator() #restore pbo viewport glViewport(0, 0, bw, bh) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST) self.unset_rgb_paint_state() log("%s(%s, %s)", glBindFramebuffer, GL_FRAMEBUFFER, self.offscreen_fbo) glBindFramebuffer(GL_FRAMEBUFFER, self.offscreen_fbo) log("%s.do_present_fbo() done", self)
def paint_yuv420(self, img_data, x, y, width, height, rowstrides): #import time #before=time.time() # OpenGL begin if not self.gldrawable.gl_begin(self.glcontext): log.error("OUCH") return False # Upload texture if self.textures[0] == 0: self.textures = glGenTextures(3) glEnable(GL_FRAGMENT_PROGRAM_ARB) if not self.yuv420_shader: self.yuv420_shader = [1] glGenProgramsARB(1, self.yuv420_shader) glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.yuv420_shader[0]) # The following fragprog is: # * MIT X11 license, Copyright (c) 2007 by: # * Michael Dominic K. <*****@*****.**> #http://www.mdk.org.pl/2007/11/17/gl-colorspace-conversions prog = """!!ARBfp1.0 # cgc version 3.1.0010, build date Feb 10 2012 # command line args: -profile arbfp1 # source file: yuv.cg #vendor NVIDIA Corporation #version 3.1.0.10 #profile arbfp1 #program main #semantic main.IN #var float2 IN.texcoord1 : $vin.TEXCOORD0 : TEX0 : 0 : 1 #var float2 IN.texcoord2 : $vin.TEXCOORD1 : TEX1 : 0 : 1 #var float2 IN.texcoord3 : $vin.TEXCOORD2 : TEX2 : 0 : 1 #var samplerRECT IN.texture1 : TEXUNIT0 : texunit 0 : 0 : 1 #var samplerRECT IN.texture2 : TEXUNIT1 : texunit 1 : 0 : 1 #var samplerRECT IN.texture3 : TEXUNIT2 : texunit 2 : 0 : 1 #var float4 IN.color : $vin.COLOR0 : COL0 : 0 : 1 #var float4 main.color : $vout.COLOR0 : COL : -1 : 1 #const c[0] = 1.1643835 2.017231 0 0.5 #const c[1] = 0.0625 1.1643835 -0.3917616 -0.81296802 #const c[2] = 1.1643835 0 1.5960271 PARAM c[3] = { { 1.1643835, 2.017231, 0, 0.5 }, { 0.0625, 1.1643835, -0.3917616, -0.81296802 }, { 1.1643835, 0, 1.5960271 } }; TEMP R0; TEMP R1; TEX R0.x, fragment.texcoord[2], texture[2], RECT; ADD R1.z, R0.x, -c[0].w; TEX R1.x, fragment.texcoord[0], texture[0], RECT; TEX R0.x, fragment.texcoord[1], texture[1], RECT; ADD R1.x, R1, -c[1]; ADD R1.y, R0.x, -c[0].w; DP3 result.color.z, R1, c[0]; DP3 result.color.y, R1, c[1].yzww; DP3 result.color.x, R1, c[2]; MOV result.color.w, fragment.color.primary; END # 10 instructions, 2 R-regs """ glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, len(prog), prog) log.error(glGetString(GL_PROGRAM_ERROR_STRING_ARB)) glEnable(GL_FRAGMENT_PROGRAM_ARB) glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.yuv420_shader[0]) glActiveTexture(GL_TEXTURE0) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[0]) glEnable(GL_TEXTURE_RECTANGLE_ARB) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[0]) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, img_data[0]) glActiveTexture(GL_TEXTURE1) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[1]) glEnable(GL_TEXTURE_RECTANGLE_ARB) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[1]) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, width / 2, height / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, img_data[1]) glActiveTexture(GL_TEXTURE2) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[2]) glEnable(GL_TEXTURE_RECTANGLE_ARB) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[2]) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, width / 2, height / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, img_data[2]) vtxarrays = 0 if vtxarrays == 1: texcoords = [[0, 0], [0, height], [width, height], [width, 0]] vtxcoords = texcoords texcoords_half = [[0, 0], [0, height / 2], [width / 2, height / 2], [width / 2, 0]] glVertexPointeri(vtxcoords) glActiveTexture(GL_TEXTURE0) glClientActiveTexture(GL_TEXTURE0) glEnableClientState(GL_TEXTURE_COORD_ARRAY) glTexCoordPointeri(texcoords) glActiveTexture(GL_TEXTURE1) glClientActiveTexture(GL_TEXTURE1) glEnableClientState(GL_TEXTURE_COORD_ARRAY) glTexCoordPointeri(texcoords_half) glActiveTexture(GL_TEXTURE2) glClientActiveTexture(GL_TEXTURE2) glEnableClientState(GL_TEXTURE_COORD_ARRAY) glTexCoordPointeri(texcoords_half) glDrawArrays(GL_QUADS, 0, 4) else: glBegin(GL_QUADS) glMultiTexCoord2i(GL_TEXTURE0, 0, 0) glMultiTexCoord2i(GL_TEXTURE1, 0, 0) glMultiTexCoord2i(GL_TEXTURE2, 0, 0) glVertex2i(0, 0) glMultiTexCoord2i(GL_TEXTURE0, 0, height) glMultiTexCoord2i(GL_TEXTURE1, 0, height / 2) glMultiTexCoord2i(GL_TEXTURE2, 0, height / 2) glVertex2i(0, height) glMultiTexCoord2i(GL_TEXTURE0, width, height) glMultiTexCoord2i(GL_TEXTURE1, width / 2, height / 2) glMultiTexCoord2i(GL_TEXTURE2, width / 2, height / 2) glVertex2i(width, height) glMultiTexCoord2i(GL_TEXTURE0, width, 0) glMultiTexCoord2i(GL_TEXTURE1, width / 2, 0) glMultiTexCoord2i(GL_TEXTURE2, width / 2, 0) glVertex2i(width, 0) glEnd() # OpenGL end #self.gldrawable.swap_buffers() # self.gldrawable.swap_buffers() glFinish() self.gldrawable.gl_end()
def plot_func(): glClear(GL_COLOR_BUFFER_BIT) p1 = [20, 20] p2 = [80, 90] p3 = [79, 42] p4 = [150, 180] p5 = [70, 220] glBegin(GL_POINTS) glVertex2i(50, 100) glVertex2i(75, 150) glVertex2i(100, 200) glVertex2iv([100, 100]) glVertex3f(78.5, 109.2, -1) glEnd() glBegin(GL_LINE_LOOP) glVertex2iv(p1) glVertex2iv(p2) glVertex2iv(p3) glVertex2iv(p4) glVertex2iv(p5) glEnd() glBegin(GL_POLYGON) glVertex2i(50, 50) glVertex2i(75, 25) glVertex2i(125, 25) glVertex2i(150, 50) glVertex2i(125, 75) glVertex2i(75, 75) glEnd() glFlush()
def _do_paint_rgb(self, bpp, img_data, x, y, width, height, rowstride, options): log("%s._do_paint_rgb(%s, %s bytes, x=%d, y=%d, width=%d, height=%d, rowstride=%d)", self, bpp, len(img_data), x, y, width, height, rowstride) drawable = self.gl_init() if not drawable: log("%s._do_paint_rgb(..) drawable is not set!", self) return False #deal with buffers uploads by wrapping them if we can, or copy to a string: if type(img_data)==buffer: if memoryview_type is not None: img_data = memoryview_type(img_data) else: img_data = str(img_data) try: self.set_rgb_paint_state() rgb_format = options.get("rgb_format") if not rgb_format: #Older servers may not tell us the pixel format, so we must infer it: if bpp==24: rgb_format = "RGB" else: assert bpp==32 rgb_format = "RGBA" #convert it to a GL constant: pformat = PIXEL_FORMAT_TO_CONSTANT.get(rgb_format) assert pformat is not None, "could not find pixel format for %s (bpp=%s)" % (rgb_format, bpp) bytes_per_pixel = len(rgb_format) #ie: BGRX -> 4 # Compute alignment and row length row_length = 0 alignment = 1 for a in [2, 4, 8]: # Check if we are a-aligned - ! (var & 0x1) means 2-aligned or better, 0x3 - 4-aligned and so on if (rowstride & a-1) == 0: alignment = a # If number of extra bytes is greater than the alignment value, # then we also have to set row_length # Otherwise it remains at 0 (= width implicitely) if (rowstride - width * bytes_per_pixel) >= alignment: row_length = width + (rowstride - width * bytes_per_pixel) / bytes_per_pixel self.gl_marker("%s %sbpp update at (%d,%d) size %dx%d (%s bytes), stride=%d, row length %d, alignment %d, using GL upload format=%s" % (rgb_format, bpp, x, y, width, height, len(img_data), rowstride, row_length, alignment, CONSTANT_TO_PIXEL_FORMAT.get(pformat))) # Upload data as temporary RGB texture glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_RGB]) glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length) glPixelStorei(GL_UNPACK_ALIGNMENT, alignment) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, self.texture_pixel_format, width, height, 0, pformat, GL_UNSIGNED_BYTE, img_data) # Draw textured RGB quad at the right coordinates glBegin(GL_QUADS) glTexCoord2i(0, 0) glVertex2i(x, y) glTexCoord2i(0, height) glVertex2i(x, y+height) glTexCoord2i(width, height) glVertex2i(x+width, y+height) glTexCoord2i(width, 0) glVertex2i(x+width, y) glEnd() # Present update to screen self.present_fbo(drawable) # present_fbo has reset state already finally: drawable.gl_end() return True