Re: [PyOpenGL-Users] Rolling spectrogram with pyopengl
Brought to you by:
mcfletch
From: Timothée L. <tim...@lp...> - 2009-12-06 12:35:51
|
Le 3 déc. 09 à 17:10, Gijs a écrit : > Hello Timothée, > > You could try to use two textures instead of one. When you display > one, you can write to the other and swap them and continue (also > called the "ping-pong" technique). Another possibility is to use > shaders to change your texture, but I'm not too sure if that is any > faster. Also, since Python is actually quite slow when compared to > languages like C, even OpenGL slows down considerably when used in > Python. So if possible, push as much commands to display lists, > vertex arrays, or VBOs. You can push all commands you use to draw > the quad to a display list, which basically brings down the number > of calls to one (since you only need to call the display list). > Hello Gijs, I am very new to both OpenGL and pyopengl worlds, but I'll try to answer to your suggestions : Since I'm doing things synchronously in one thread, I don't see how using two textures could make the whole thing faster. Moreover, there's one single bottleneck which is the writing of the two columns of the texture (that's two times approx. 500 pixels every 20 ms, with the glTexSubImage2D calls). The display in itself appears much below in the profile, so converting it to a display list is not my first priority. > Regards, Gijs > > PS: While it is not necessary, I would supply the glTexImage2D call, > that you use to create the texture, an array with zeros the size of > the texture. This way you know that the texture is zero everywhere. Right, that would make the initialization more deterministic :) Thanks for your comments ! Timothée > > On 3-12-2009 15:19, Timothée Lecomte wrote: >> Dear pyopengl users, >> >> I am writing (as a hobby) an application that does real-time >> visualization of audio data. The main widget is a rolling >> spectrogram, >> that is a colored image where the horizontal axis is the time, the >> vertical axis is the frequency, and the color of each pixel >> represents >> the intensity of the corresponding spectrum component (see >> http://www.flickr.com/photos/41584197@N03/3832486029/in/set-72157622072708326/ >> for example). Each column of the image is computed with a FFT of the >> audio data every 20 ms or so, and the whole image is displayed on >> screen >> and "rolls" and time goes by. >> >> I am trying to use OpenGL to improve the performance of the part of >> the >> application that displays the image on the screen, but I can't >> manage to >> get it really faster than a simple 2D blitting, so I am asking for >> your >> help ! >> >> Currently, I first set up a texture with the following : >> >> # Create Texture >> GL.glGenTextures(1, self.texture) # generate one texture name >> GL.glBindTexture(GL.GL_TEXTURE_2D, self.texture) # bind a 2d >> texture to the generated name >> GL.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1) >> GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, >> 2*self.canvas_width, height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, >> None) >> GL.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, >> GL.GL_CLAMP) >> GL.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, >> GL.GL_CLAMP) >> GL.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, >> GL.GL_REPEAT) >> GL.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, >> GL.GL_REPEAT) >> GL.glTexParameterf(GL.GL_TEXTURE_2D, >> GL.GL_TEXTURE_MAG_FILTER, >> GL.GL_NEAREST) >> GL.glTexParameterf(GL.GL_TEXTURE_2D, >> GL.GL_TEXTURE_MIN_FILTER, >> GL.GL_NEAREST) >> GL.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, >> GL.GL_DECAL) >> >> Then, every 20 ms or so, I modify two columns of that texture with : >> GL.glTexSubImage2D(GL.GL_TEXTURE_2D, 0, self.offset, 0, 1, >> self.height, GL.GL_BGRA, GL.GL_UNSIGNED_BYTE, byteString) >> GL.glTexSubImage2D(GL.GL_TEXTURE_2D, 0, self.offset + >> self.canvas_width, 0, 1, self.height, GL.GL_BGRA, >> GL.GL_UNSIGNED_BYTE, >> byteString) >> >> And I draw part of that texture to my widget with : >> GL.glLoadIdentity() >> GL.glBegin(GL.GL_QUADS) >> xoff = float(self.offset)/(2*self.canvas_width) >> GL.glTexCoord2f(xoff, 0.) >> GL.glVertex2f(0, 0) >> GL.glTexCoord2f(1.+xoff , 0.) >> GL.glVertex2f(2*self.canvas_width, 0) >> GL.glTexCoord2f(1.+xoff, 1.) >> GL.glVertex2f(2*self.canvas_width, self.height) >> GL.glTexCoord2f(xoff, 1.) >> GL.glVertex2f(0, self.height) >> GL.glEnd() >> >> Profiling shows that the two GL.glTexSubImage2D take a lot of time >> (more >> than twice as much as the whole drawing part) whereas it's "just" two >> single columns of the texture being updated... What can I do to >> optimize >> this ? Is there a smarter way to achieve the same result ? >> >> Thanks for your help ! >> >> Timothée Lecomte >> >> >> ------------------------------------------------------------------------------ >> Join us December 9, 2009 for the Red Hat Virtual Experience, >> a free event focused on virtualization and cloud computing. >> Attend in-depth sessions from your desk. Your couch. Anywhere. >> http://p.sf.net/sfu/redhat-sfdev2dev >> _______________________________________________ >> PyOpenGL Homepage >> http://pyopengl.sourceforge.net >> _______________________________________________ >> PyOpenGL-Users mailing list >> PyO...@li... >> https://lists.sourceforge.net/lists/listinfo/pyopengl-users >> |