Jump to content
  • Advertisement
Sign in to follow this  
0beron

OpenGL Name stack based picking problem

This topic is 4306 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm working on a 3d version of a 2d board game, in which square tiles can be placed onto a board made up of square spaces (in the 3d version the board squares can be oriented vertically and upside down as well as flat like in the 2d version you play on a table). The board squares are coloured quads, and the game tiles fit within a board square, but are made up of a number of sub-objects which are just a selection of coloured triangles. I want to be able to pick these sub objects with the mouse, and I've set up the openGL name stack to do this. The board squares are drawn by feeding absolute coordinates into glVertex3fv(), and their names work fine - picking of board squares is accurate from any viewing position and orientation. The game tiles are drawn relative to the corner of the tile, and are shuffled into place using glTranslatef. When drawn to the framebuffer the tile appears in the correct position, but picking only seems to work accurately when the tile is placed at the origin. Applying a small translation to it causes the picking to shift off to the side, and apllying a large translation means I can no longer locate the place where the tile is picked since it so far from where the tile actually appears. What part of the pipeline could be causing this effect, given that the board squares work fine from any angle? My code is a bit scattered, and it's written in Python - I'm happy to post some relevant snippets if no-one can guess the problem from the description above. Any help much appreciated, thanks.

Share this post


Link to post
Share on other sites
Advertisement
It sounds like you don't have the same translations for the picking routine and normal rendering.

Share this post


Link to post
Share on other sites
The picking routine IS the normal rendering routine at the moment...

I'll post some code shortly (currently it is half past midnight and I need to be at work at 9...)

Share this post


Link to post
Share on other sites
Ok, here are some snippets...

This is the draw routine for the game tile, where the names are assigned.

def draw(self):
print glGetInteger(GL_RENDER_MODE)
gen.reset()
glColor3f(0.8,0.8,0.8)
for road in self.roads:
if road['model'] is not None:
glPushName(gen.generatename())
road['model'].draw()
glPopName()
glColor3f(0.4,1.0,0.4)
for farm in self.farms:
if farm['model'] is not None:
glPushName(gen.generatename())
farm['model'].draw()
glPopName()



The above is called below, in the draw routine for the board squares, which render either a flat quad, or the tile occupying the square. The two translations either side of self.tile.draw are the ones giving me trouble. They work fine for drawing the tile but they seem to disrupt the picking if they are anything other than a zero vector.

def draw(self):

print glGetInteger(GL_RENDER_MODE)
if self.tile is not None:
c = list(self.centre())
c[self.uaxis]-=0.5
c[self.vaxis]-=0.5
glTranslatef(c[0],c[1],c[2])
self.tile.draw()
glTranslatef(-c[0],-c[1],-c[2])
return
#glPolygonOffset(1.1,4)
#glEnable(GL_POLYGON_OFFSET_FILL)
glColor3fv(self.col)
p = Vertex()
p[self.naxis] = (1-self.ori[self.naxis])/2.0
glBegin(GL_QUADS)
glNormal3fv(self.ori)
for i in [0.0,1.0]:
for j in [i,1.0-i]:
p[self.uaxis] = i
p[self.vaxis] = j
glVertex3fv((p+self.pos).p)
glEnd()



The whole process is started from here:

def pick(self, event):
self.focus()
self.tkRecordMouse(event)
if self.pickmode == PM_BUFFER:
glMatrixMode(GL_MODELVIEW)
glPushMatrix()
glInitNames()
buffer = glSelectWithCallback(event.x, event.y, lambda: self.bufferdraw(pick=True), 1, 1)
glMatrixMode(GL_MODELVIEW)
glPopMatrix()
self.pickcallback(buffer)
else:
self.pick_xyz(event)


lambda: self.bufferdraw(pick=True) results in a call to the main drawing routine, and the pick argument specifies that everything should be redrawn instead of calling the stored display lists. self.pickcallback just passes the buffer back to the calling class.

This works perfectly for the board squares ( I push a name onto the stack before drawing the whole board and don't pop it until the end, and everything that is drawn gets that name.) Picking the board squares works perfectly, but the tiles drift off from where they actually appear...

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!