Thread: [PyOpenGL-Users] Drawing a bitmap at "native" resolution
Brought to you by:
mcfletch
|
From: Christopher B. <Chr...@no...> - 2011-05-02 21:18:57
|
Hi folks, Anyone know of a performant way to draw a bitmap at its "native" resolution -- i.e. one pixel in the bitmap is one pixel on screen, regardless of zoom level, etc. I think I've heard this referred to as "billboard" view, but that may be a term specific to one visualization lib (VTK, maybe)? Anyway, the task at hand is using bitmaps fonts as textures to do simple text labels, lot of them, in a scientific visualization app. For each data point ( up to 100s of thousands ) we need a little text label. But we want the text to not change size as the user zooms in or out. Our current solution is something like this: Each label is a texture (actually, I think a piece of a big texture). When rendering, we calculate where the corners of the label should be in world coordinates, so that it scales to one pixel per pixel. This does produce the desired result. The problem with this is that with each draw call, those coordinates need to be re-calculated. This can be pretty slow, particularly in python. We've got numpy doing it now, but that requires some pretty big arrays of coordinates to be kept around, which take up memory, and is still a bit pokey. Is there any way to do this directly in OpenGL? Or, if not, it seems that we may be able to use a shader to do that coordinate calculation -- should that be doable? I have no idea where to even start with that. (this a 2D app, but I think the principle is the same either way) Any suggestions would be appreciated. -Chris -- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chr...@no... |
|
From: Ian M. <geo...@gm...> - 2011-05-03 05:31:26
|
On Mon, May 2, 2011 at 3:18 PM, Christopher Barker <Chr...@no...>wrote: > Hi folks, > > Anyone know of a performant way to draw a bitmap at its "native" > resolution -- i.e. one pixel in the bitmap is one pixel on screen, > regardless of zoom level, etc. I think I've heard this referred to as > "billboard" view, but that may be a term specific to one visualization > lib (VTK, maybe)? > > Anyway, the task at hand is using bitmaps fonts as textures to do simple > text labels, lot of them, in a scientific visualization app. > > For each data point ( up to 100s of thousands ) we need a little text > label. But we want the text to not change size as the user zooms in or out. > There's not a way to get around projecting the labels' locations on screen. You'd have to use gluProject(...). If you want to be fancy, you can use a vertex shader to project to get each coordinate. >From there, set up a 2D view. Then, draw each label at the screen coordinate of its projected location, using textured quads the same size as your textures. Ian |
|
From: Nicolas R. <Nic...@in...> - 2011-05-03 07:18:49
|
Here is a quick example:
import sys
import OpenGL.GL as gl
import OpenGL.GLU as glu
import OpenGL.GLUT as glut
def on_display():
global theta, phi
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
gl.glColor(0,0,0,1)
# Push rotation matrix onto stack
gl.glPushMatrix()
gl.glRotatef(theta, 0,0,1)
gl.glRotatef(phi, 0,1,0)
# Transform coordinates from 3d space to window 2d
modelview = gl.glGetDoublev(gl.GL_MODELVIEW_MATRIX)
projection= gl.glGetDoublev(gl.GL_PROJECTION_MATRIX)
viewport = gl.glGetIntegerv(gl.GL_VIEWPORT)
coords = [ ( 1, 1, 1), ( 1, 1, -1),
( 1, -1, 1), (-1, 1, 1),
( 1, -1, -1), (-1, -1, 1),
(-1, 1, -1), (-1, -1, -1) ]
pcoords = []
for x,y,z in coords:
pcoords.append(glu.gluProject(x,y,z, modelview, projection, viewport))
# Draw cube
glut.glutWireCube(2)
# Pop out rotation matrix
gl.glPopMatrix()
# Setup an orthogonal projection
gl.glMatrixMode(gl.GL_PROJECTION)
gl.glPushMatrix()
gl.glLoadIdentity()
gl.glOrtho(0, viewport[2], 0, viewport[3], -1, 1)
gl.glMatrixMode(gl.GL_MODELVIEW)
gl.glPushMatrix()
gl.glLoadIdentity()
for x,y,z in pcoords:
gl.glBegin(gl.GL_LINE_LOOP)
gl.glVertex(x-20,y-5,0), gl.glVertex(x-20,y+5,0)
gl.glVertex(x+20,y+5,0), gl.glVertex(x+20,y-5,0)
gl.glEnd()
gl.glMatrixMode(gl.GL_PROJECTION)
gl.glPopMatrix()
gl.glMatrixMode(gl.GL_MODELVIEW)
gl.glPopMatrix()
glut.glutSwapBuffers()
def on_reshape(width, height):
gl.glViewport(0, 0, width, height)
gl.glMatrixMode( gl.GL_PROJECTION )
gl.glLoadIdentity( )
glu.gluPerspective( 45.0, float(width)/float(height), 2.0, 10.0 )
gl.glMatrixMode( gl.GL_MODELVIEW )
gl.glLoadIdentity( )
gl.glTranslatef( 0.0, 0.0, -5.0 )
def on_keyboard(key, x, y):
if key == '\033':
sys.exit()
def on_timer(value):
global theta, phi
theta += 0.25
phi += 0.25
glut.glutPostRedisplay()
glut.glutTimerFunc(10, on_timer, 0)
if __name__ == '__main__':
glut.glutInit(sys.argv)
glut.glutInitDisplayMode(glut.GLUT_DOUBLE | glut.GLUT_RGB | glut.GLUT_DEPTH)
glut.glutCreateWindow("Python billboard")
glut.glutReshapeWindow(400, 400)
glut.glutDisplayFunc(on_display)
glut.glutReshapeFunc(on_reshape)
glut.glutKeyboardFunc(on_keyboard)
glut.glutTimerFunc(10, on_timer, 0)
gl.glClearColor(1,1,1,1);
theta, phi = 0, 0
glut.glutMainLoop()
Nicolas
On May 3, 2011, at 7:31 AM, Ian Mallett wrote:
> On Mon, May 2, 2011 at 3:18 PM, Christopher Barker <Chr...@no...> wrote:
> Hi folks,
>
> Anyone know of a performant way to draw a bitmap at its "native"
> resolution -- i.e. one pixel in the bitmap is one pixel on screen,
> regardless of zoom level, etc. I think I've heard this referred to as
> "billboard" view, but that may be a term specific to one visualization
> lib (VTK, maybe)?
>
> Anyway, the task at hand is using bitmaps fonts as textures to do simple
> text labels, lot of them, in a scientific visualization app.
>
> For each data point ( up to 100s of thousands ) we need a little text
> label. But we want the text to not change size as the user zooms in or out.
> There's not a way to get around projecting the labels' locations on screen. You'd have to use gluProject(...). If you want to be fancy, you can use a vertex shader to project to get each coordinate.
>
> From there, set up a 2D view. Then, draw each label at the screen coordinate of its projected location, using textured quads the same size as your textures.
>
> Ian
> ------------------------------------------------------------------------------
> WhatsUp Gold - Download Free Network Management Software
> The most intuitive, comprehensive, and cost-effective network
> management toolset available today. Delivers lowest initial
> acquisition cost and overall TCO of any competing solution.
> http://p.sf.net/sfu/whatsupgold-sd_______________________________________________
> PyOpenGL Homepage
> http://pyopengl.sourceforge.net
> _______________________________________________
> PyOpenGL-Users mailing list
> PyO...@li...
> https://lists.sourceforge.net/lists/listinfo/pyopengl-users
|
|
From: Christopher B. <Chr...@no...> - 2011-05-03 15:04:19
|
On 5/2/11 10:31 PM, Ian Mallett wrote: > There's not a way to get around projecting the labels' locations on > screen. right -- I knew that the trick was how to project the location, but not the label itself. > You'd have to use gluProject(...). If you want to be fancy, > you can use a vertex shader to project to get each coordinate. but how? Anyway, it looks like that may not be neccessary, so I can put off learning that. > From there, set up a 2D view. Then, draw each label at the screen > coordinate of its projected location, using textured quads the same size > as your textures. this is the part I don't get -- but i see that Nicolas has given me a demo of that! thanks, -Chris -- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chr...@no... |
|
From: Christopher B. <Chr...@no...> - 2011-05-03 15:05:35
|
On 5/3/11 12:18 AM, Nicolas Rougier wrote:
>
>
> Here is a quick example:
Very nice, thanks!
It's going to take me a bit to digest that, but it looks like all the
key pieces are there that I need.
And it worked out of the box for me.
again, thanks!
-Chris
>
>
> import sys
> import OpenGL.GL as gl
> import OpenGL.GLU as glu
> import OpenGL.GLUT as glut
>
>
> def on_display():
> global theta, phi
>
> gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
> gl.glColor(0,0,0,1)
>
> # Push rotation matrix onto stack
> gl.glPushMatrix()
> gl.glRotatef(theta, 0,0,1)
> gl.glRotatef(phi, 0,1,0)
>
> # Transform coordinates from 3d space to window 2d
> modelview = gl.glGetDoublev(gl.GL_MODELVIEW_MATRIX)
> projection= gl.glGetDoublev(gl.GL_PROJECTION_MATRIX)
> viewport = gl.glGetIntegerv(gl.GL_VIEWPORT)
> coords = [ ( 1, 1, 1), ( 1, 1, -1),
> ( 1, -1, 1), (-1, 1, 1),
> ( 1, -1, -1), (-1, -1, 1),
> (-1, 1, -1), (-1, -1, -1) ]
> pcoords = []
> for x,y,z in coords:
> pcoords.append(glu.gluProject(x,y,z, modelview, projection, viewport))
>
> # Draw cube
> glut.glutWireCube(2)
>
> # Pop out rotation matrix
> gl.glPopMatrix()
>
> # Setup an orthogonal projection
> gl.glMatrixMode(gl.GL_PROJECTION)
> gl.glPushMatrix()
> gl.glLoadIdentity()
> gl.glOrtho(0, viewport[2], 0, viewport[3], -1, 1)
> gl.glMatrixMode(gl.GL_MODELVIEW)
> gl.glPushMatrix()
> gl.glLoadIdentity()
> for x,y,z in pcoords:
> gl.glBegin(gl.GL_LINE_LOOP)
> gl.glVertex(x-20,y-5,0), gl.glVertex(x-20,y+5,0)
> gl.glVertex(x+20,y+5,0), gl.glVertex(x+20,y-5,0)
> gl.glEnd()
> gl.glMatrixMode(gl.GL_PROJECTION)
> gl.glPopMatrix()
> gl.glMatrixMode(gl.GL_MODELVIEW)
> gl.glPopMatrix()
> glut.glutSwapBuffers()
>
>
> def on_reshape(width, height):
> gl.glViewport(0, 0, width, height)
> gl.glMatrixMode( gl.GL_PROJECTION )
> gl.glLoadIdentity( )
> glu.gluPerspective( 45.0, float(width)/float(height), 2.0, 10.0 )
> gl.glMatrixMode( gl.GL_MODELVIEW )
> gl.glLoadIdentity( )
> gl.glTranslatef( 0.0, 0.0, -5.0 )
>
>
> def on_keyboard(key, x, y):
> if key == '\033':
> sys.exit()
>
> def on_timer(value):
> global theta, phi
> theta += 0.25
> phi += 0.25
> glut.glutPostRedisplay()
> glut.glutTimerFunc(10, on_timer, 0)
>
>
> if __name__ == '__main__':
> glut.glutInit(sys.argv)
> glut.glutInitDisplayMode(glut.GLUT_DOUBLE | glut.GLUT_RGB | glut.GLUT_DEPTH)
> glut.glutCreateWindow("Python billboard")
> glut.glutReshapeWindow(400, 400)
> glut.glutDisplayFunc(on_display)
> glut.glutReshapeFunc(on_reshape)
> glut.glutKeyboardFunc(on_keyboard)
> glut.glutTimerFunc(10, on_timer, 0)
> gl.glClearColor(1,1,1,1);
> theta, phi = 0, 0
> glut.glutMainLoop()
>
>
> Nicolas
>
>
>
>
> On May 3, 2011, at 7:31 AM, Ian Mallett wrote:
>
>> On Mon, May 2, 2011 at 3:18 PM, Christopher Barker
>> <Chr...@no... <mailto:Chr...@no...>> wrote:
>>
>> Hi folks,
>>
>> Anyone know of a performant way to draw a bitmap at its "native"
>> resolution -- i.e. one pixel in the bitmap is one pixel on screen,
>> regardless of zoom level, etc. I think I've heard this referred to as
>> "billboard" view, but that may be a term specific to one visualization
>> lib (VTK, maybe)?
>>
>> Anyway, the task at hand is using bitmaps fonts as textures to do
>> simple
>> text labels, lot of them, in a scientific visualization app.
>>
>> For each data point ( up to 100s of thousands ) we need a little text
>> label. But we want the text to not change size as the user zooms
>> in or out.
>>
>> There's not a way to get around projecting the labels' locations on
>> screen. You'd have to use gluProject(...). If you want to be fancy,
>> you can use a vertex shader to project to get each coordinate.
>>
>> From there, set up a 2D view. Then, draw each label at the screen
>> coordinate of its projected location, using textured quads the same
>> size as your textures.
>>
>> Ian
>> ------------------------------------------------------------------------------
>> WhatsUp Gold - Download Free Network Management Software
>> The most intuitive, comprehensive, and cost-effective network
>> management toolset available today. Delivers lowest initial
>> acquisition cost and overall TCO of any competing solution.
>> http://p.sf.net/sfu/whatsupgold-sd_______________________________________________
>> PyOpenGL Homepage
>> http://pyopengl.sourceforge.net
>> _______________________________________________
>> PyOpenGL-Users mailing list
>> PyO...@li...
>> https://lists.sourceforge.net/lists/listinfo/pyopengl-users
>
--
Christopher Barker, Ph.D.
Oceanographer
Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception
Chr...@no...
|