Added a new function+struct to glutil that takes care of reading in the OpenGL data needed for gluProject/gluUnProject. This allows retopo and sculptmode to share some of the same code, and is probably useful elsewhere as well.

This commit is contained in:
Nicholas Bishop 2007-01-17 03:57:01 +00:00
parent a3c9ae8a88
commit 5f798002c9
6 changed files with 58 additions and 45 deletions

@ -30,6 +30,9 @@
#ifndef BDR_SCULPTMODE_H
#define BDR_SCULPTMODE_H
/* For bglMats */
#include "BIF_glutil.h"
#include "transform.h"
struct uiBlock;
@ -65,10 +68,7 @@ typedef struct PropsetData {
} PropsetData;
typedef struct SculptSession {
/* Cache of the OpenGL matrices */
double modelviewmat[16];
double projectionmat[16];
int viewport[4];
bglMats mats;
/* An array of lists; array is sized as
large as the number of verts in the mesh,

@ -213,5 +213,13 @@ void set_inverted_drawing(int enable);
/* own working polygon offset */
void bglPolygonOffset(float dist);
/* For caching opengl matrices (gluProject/gluUnProject) */
typedef struct bglMats {
double modelview[16];
double projection[16];
int viewport[4];
} bglMats;
void bgl_get_mats(bglMats *mats);
#endif /* BIF_GLUTIL_H */

@ -32,14 +32,15 @@
#include "DNA_vec_types.h"
/* For bglMats */
#include "BIF_glutil.h"
struct EditVert;
struct Mesh;
struct View3D;
typedef struct RetopoViewData {
/* OpenGL matrices */
double modelviewmat[16], projectionmat[16];
int viewport[4];
bglMats mats;
char queue_matrix_update;
} RetopoViewData;

@ -596,6 +596,29 @@ void bglEnd(void)
}
/* Uses current OpenGL state to get view matrices for gluProject/gluUnProject */
void bgl_get_mats(bglMats *mats)
{
const double badvalue= 1.0e-6;
glGetDoublev(GL_MODELVIEW_MATRIX, mats->modelview);
glGetDoublev(GL_PROJECTION_MATRIX, mats->projection);
glGetIntegerv(GL_VIEWPORT, (GLint *)mats->viewport);
/* Very strange code here - it seems that certain bad values in the
modelview matrix can cause gluUnProject to give bad results. */
if(mats->modelview[0] < badvalue &&
mats->modelview[0] > -badvalue)
mats->modelview[0]= 0;
if(mats->modelview[5] < badvalue &&
mats->modelview[5] > -badvalue)
mats->modelview[5]= 0;
/* Set up viewport so that gluUnProject will give correct values */
mats->viewport[0] = 0;
mats->viewport[1] = 0;
}
/* *************** glPolygonOffset hack ************* */
// both temporal, so here for now (ton)

@ -292,7 +292,7 @@ void retopo_paint_apply()
for(i=0; i<hitcount; ++i) {
RetopoPaintPoint *intersection= BLI_findlink(&rpd->intersections,i);
retopo_do_2d(G.vd,&intersection->loc.x, hitco, 1);
retopo_do_2d(rpd->paint_v3d,&intersection->loc.x, hitco, 1);
intersection->eve= addvertlist(hitco, NULL);
intersection->eve->f= SELECT;
}
@ -322,7 +322,7 @@ void add_rppoint(RetopoPaintLine *l, short x, short y)
BLI_addtail(&l->points,p);
p->index= p->prev?p->prev->index+1:0;
retopo_do_2d(G.vd, &p->loc.x, p->co, 1);
retopo_do_2d(G.editMesh->retopo_paint_data->paint_v3d, &p->loc.x, p->co, 1);
}
RetopoPaintLine *add_rpline(RetopoPaintData *rpd)
{
@ -422,9 +422,9 @@ void retopo_paint_view_update(struct View3D *v3d)
for(l= rpd->lines.first; l; l= l->next) {
for(p= l->points.first; p; p= p->next) {
gluProject(p->co[0],p->co[1],p->co[2], v3d->retopo_view_data->modelviewmat,
v3d->retopo_view_data->projectionmat,
(GLint *)v3d->retopo_view_data->viewport, &ux, &uy, &uz);
gluProject(p->co[0],p->co[1],p->co[2], v3d->retopo_view_data->mats.modelview,
v3d->retopo_view_data->mats.projection,
(GLint *)v3d->retopo_view_data->mats.viewport, &ux, &uy, &uz);
p->loc.x= ux;
p->loc.y= uy;
}
@ -753,18 +753,18 @@ void retopo_do_2d(View3D *v3d, short proj[2], float *v, char adj)
if(depth==v3d->depths->depth_range[1]) {
if(adj) {
/* Find the depth of (0,0,0); */
gluProject(0,0,0,v3d->retopo_view_data->modelviewmat,
v3d->retopo_view_data->projectionmat,
(GLint *)v3d->retopo_view_data->viewport,&px,&py,&pz);
gluProject(0,0,0,v3d->retopo_view_data->mats.modelview,
v3d->retopo_view_data->mats.projection,
(GLint *)v3d->retopo_view_data->mats.viewport,&px,&py,&pz);
depth= pz;
}
else return;
}
/* Find 3D location with new depth (unproject) */
gluUnProject(proj[0],proj[1],depth,v3d->retopo_view_data->modelviewmat,
v3d->retopo_view_data->projectionmat,
(GLint *)v3d->retopo_view_data->viewport,&px,&py,&pz);
gluUnProject(proj[0],proj[1],depth,v3d->retopo_view_data->mats.modelview,
v3d->retopo_view_data->mats.projection,
(GLint *)v3d->retopo_view_data->mats.viewport,&px,&py,&pz);
v[0]= px;
v[1]= py;
@ -778,8 +778,8 @@ void retopo_do_vert(View3D *v3d, float *v)
double px, py, pz;
/* Find 2D location (project) */
gluProject(v[0],v[1],v[2],v3d->retopo_view_data->modelviewmat,v3d->retopo_view_data->projectionmat,
(GLint *)v3d->retopo_view_data->viewport,&px,&py,&pz);
gluProject(v[0],v[1],v[2],v3d->retopo_view_data->mats.modelview,v3d->retopo_view_data->mats.projection,
(GLint *)v3d->retopo_view_data->mats.viewport,&px,&py,&pz);
proj[0]= px;
proj[1]= py;
@ -859,10 +859,7 @@ void retopo_matrix_update(View3D *v3d)
rvd->queue_matrix_update= 1;
}
if(rvd && rvd->queue_matrix_update) {
glGetDoublev(GL_MODELVIEW_MATRIX, rvd->modelviewmat);
glGetDoublev(GL_PROJECTION_MATRIX, rvd->projectionmat);
glGetIntegerv(GL_VIEWPORT, (GLint *)rvd->viewport);
rvd->viewport[0]= rvd->viewport[1]= 0;
bgl_get_mats(&rvd->mats);
rvd->queue_matrix_update= 0;
}

@ -636,29 +636,13 @@ void sculptmode_rem_tex(void *junk0,void *junk1)
void init_sculptmatrices()
{
SculptSession *ss= sculpt_session();
const double badvalue= 1.0e-6;
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glMultMatrixf(OBACT->obmat);
glGetDoublev(GL_MODELVIEW_MATRIX, ss->modelviewmat);
glGetDoublev(GL_PROJECTION_MATRIX, ss->projectionmat);
glGetIntegerv(GL_VIEWPORT, (GLint *)ss->viewport);
bgl_get_mats(&ss->mats);
/* Very strange code here - it seems that certain bad values in the
modelview matrix can cause gluUnProject to give bad results. */
if(ss->modelviewmat[0] < badvalue &&
ss->modelviewmat[0] > -badvalue)
ss->modelviewmat[0]= 0;
if(ss->modelviewmat[5] < badvalue &&
ss->modelviewmat[5] > -badvalue)
ss->modelviewmat[5]= 0;
/* Set up viewport so that gluUnProject will give correct values */
ss->viewport[0] = 0;
ss->viewport[1] = 0;
glPopMatrix();
}
@ -692,8 +676,8 @@ vec3f unproject(const short x, const short y, const float z)
double ux, uy, uz;
vec3f p;
gluUnProject(x,y,z, ss->modelviewmat, ss->projectionmat,
(GLint *)ss->viewport, &ux, &uy, &uz );
gluUnProject(x,y,z, ss->mats.modelview, ss->mats.projection,
(GLint *)ss->mats.viewport, &ux, &uy, &uz );
p.x= ux;
p.y= uy;
p.z= uz;
@ -706,8 +690,8 @@ void project(const float v[3], short p[2])
SculptSession *ss= sculpt_session();
double ux, uy, uz;
gluProject(v[0],v[1],v[2], ss->modelviewmat, ss->projectionmat,
(GLint *)ss->viewport, &ux, &uy, &uz);
gluProject(v[0],v[1],v[2], ss->mats.modelview, ss->mats.projection,
(GLint *)ss->mats.viewport, &ux, &uy, &uz);
p[0]= ux;
p[1]= uy;
}