Skip to main content
GameDev.net gamedev.net
🔒 Locked

Name stack based picking problem

Started by 0beron Sep 30, 2006 at 8:19 PM 3 replies 800+ views
Original Post
0beron
0beron
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.
Redien
Redien
It sounds like you don't have the same translations for the picking routine and normal rendering.
0beron
0beron
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...)
0beron
0beron
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...

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.