OpenGL 3D Picking -
i read many sample code opengl picking. of them use gluperspective funcion projection.i'm using glortho instead of gluperspective function.
and selection function below(drawbuffer paint code):
void selection( int x, int y ) { gluint buffer[512]; glint hits; glint viewport[4]; glgetintegerv(gl_viewport, viewport); glselectbuffer(512, buffer); (void)glrendermode(gl_select); glinitnames(); glpushname(0); glmatrixmode(gl_projection); glpushmatrix(); glloadidentity(); gldouble w = (double)m_clientrect.width(); gldouble h = (double)m_clientrect.height(); glupickmatrix((gldouble)x, (gldouble)(viewport[3] - y), 500, 500, viewport); glortho(-w / 2, w / 2, -h / 2, h / 2, -1000000.0, 100000.0); glmatrixmode(gl_modelview); drawbuffer(); glmatrixmode(gl_projection); glpopmatrix(); glmatrixmode(gl_modelview); hits = glrendermode(gl_render); if (hits > 0) { trace(_t("%d %d %d %d %d\n"), hits, buffer[0], buffer[1], buffer[2], buffer[3]); } }
but doesn't work, can't figure out reason? problem is: when using gldrawarrays function draw many lines, how can call glloadname flag each of them?
my raytracer algorithm follow:
void cgraphicview::kdsearch( picking_vertex *root, cray *pray, picking_vertex **found, double *dcursplit ) { if (null == root) { return; } searchnode(root, m_pray, m_globaltmin, m_globaltmax, found, dcursplit); } void cgraphicview::searchnode( picking_vertex *node, cray *pray, double tmin, double tmax, picking_vertex **found, double *dcursplit ) { if (null == node) { return; } if (node->bleaf) { searchleaf(node, pray, tmin, tmax, found, dcursplit); } else { searchsplit(node, pray, tmin, tmax, found, dcursplit); } } void cgraphicview::searchsplit( picking_vertex *split, cray *pray, double tmin, double tmax, picking_vertex **found, double *dcursplit ) { if (null == split) { return; } int axis = split->axis; double thit = pray->getsplit(axis, split->coor[axis]); point3d psrc(split->coor[0], split->coor[1], split->coor[2]); double scale = m_pcam->getscale(); double disp2l = distancep2l(psrc, m_raystart, m_rayend); if (disp2l * scale < max_distance && thit < *dcursplit) { *found = split; *dcursplit = thit; } picking_vertex *first = null, *second = null; if (is_equal_float(pray->m_direction[axis], 0.0)) { first = (pray->m_origin[axis] < split->coor[axis]) ? split->left : split->right; } else { first = (pray->m_direction[axis] > 0.0) ? split->left: split->right; second = (pray->m_direction[axis] < 0.0) ? split->left : split->right; } if ((thit >= tmax || thit < 0)) { searchnode(first, pray, tmin, tmax, found, dcursplit); } else if (thit <= tmin) { searchnode(second, pray, tmin, tmax, found, dcursplit); } else { searchnode(first, pray, tmin, thit, found, dcursplit); } } void cgraphicview::searchleaf( picking_vertex *leaf, cray *pray, double tmin, double tmax, picking_vertex **found, double *dcursplit ) { if (null == leaf) { return; } int axis = leaf->axis; double thit = pray->getsplit(axis, leaf->coor[axis]); point3d psrc(leaf->coor[0], leaf->coor[1], leaf->coor[2]); double scale = m_pcam->getscale(); double disp2l = distancep2l(psrc, m_raystart, m_rayend); if (disp2l * scale < max_distance && thit < *dcursplit) { *found = leaf; *dcursplit = thit; } continuesearch(leaf, pray, tmin, tmax, found, dcursplit); } void cgraphicview::continuesearch( picking_vertex *leaf, cray *pray, double tmin, double tmax, picking_vertex **found, double *dcursplit ) { if (is_equal_float(tmax, m_globaltmax)) { return; } else { tmin = tmax; tmax = m_globaltmax; searchnode(m_root, pray, tmin, tmax, found, dcursplit); } }
when using gldrawarrays function draw many lines, how can call glloadname flag each of them?
you can't. , frankly: you should not use opengl selection mode in first place! it's slow, no current driver supports (you'll drop software emulation mode it), doesn't work (well) shaders , cumbersome use.
a far better alternative either backproject selection rays scene or (if modern opengl used) use transform feedback buffer applied in bounding boxes (or other kind of bounding volume) sort geometry screen space kd-tree can select what's been clicked onto.
Comments
Post a Comment