Комплектация с помощью glRenderMode

Я пытаюсь сделать выбор OpenGL, поэтому я следил за этим постом (Выбор OpenGL в режиме выбора ), который, кажется, имеет рабочее решение, но я не могу заставить мою работу. У меня есть 3D текстурированный многоугольник в моей сцене, и я хотел бы знать, когда я нажимаю на него.

Вот мой код:

Метод мыши, который запускает сбор при щелчке правой кнопкой мыши:

void mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if(event->button()==Qt::RightButton){
pickObjects(event->pos().x(),event->pos().y());
}
}

Метод pickObjects:

#define BUFSIZE 512
void pickObjects(int x, int y)
{
GLint viewport[4];
GLint hits;

GLuint selectBuf[BUFSIZE];
glSelectBuffer (BUFSIZE, selectBuf);

glRenderMode (GL_SELECT);

glMatrixMode (GL_PROJECTION);
glPushMatrix ();
glLoadIdentity ();

glGetIntegerv (GL_VIEWPORT, viewport);

gluPickMatrix ((GLdouble) x, (GLdouble) (viewport[3] - y), 5.0, 5.0, viewport);
gluPerspective(fov, this->width() / this->height(), 0.1, 1000);

glMatrixMode(GL_MODELVIEW);

glInitNames();

makeCustomAnnot(GL_SELECT);

int hits=0;

glMatrixMode (GL_PROJECTION);
glPopMatrix ();

glMatrixMode(GL_MODELVIEW);

hits = glRenderMode (GL_RENDER);
if (hits != 0)
{
cout<<"FOUND " << hits << " hit(s)"<<endl; //ALWAYS GIVES 0 HITS
processHits(hits,selectBuf);
}

}

Метод processHits:

void processHits(GLint inHits, GLuint buffer[])
{
unsigned int i, j;
GLuint names, *ptr, minZ,*ptrNames, numberOfNames;

ptr = (GLuint *) buffer;
minZ = 0xffffffff;
for (i = 0; i < inHits; i++) {
names = *ptr;
ptr++;
if (*ptr < minZ) {
numberOfNames = names;
minZ = *ptr;
ptrNames = ptr+2;
}
ptr += names+2;
}

cout << "Nearest: ";
ptr = ptrNames;
for (j = 0; j < numberOfNames; j++,ptr++) {
cout<< *ptr ;
}
}

Метод рисования объекта:

void makeCustomAnnot(GLenum mode){

glEnable(GL_TEXTURE_2D);
glColor3f(1,1,1);
GLuint j=0;

QImage img("img.jpg");
img=QGLWidget::convertToGLFormat(img);

GLuint texturesAnnot[1];
glBindTexture( GL_TEXTURE_2D, texturesAnnot[0] );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.width(), img.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

if(mode == GL_SELECT){
glPushName (j);
}

glBegin(GL_QUADS);
glTexCoord2d(0,0);glVertex3d(x4,y4,z4);
glTexCoord2d(1,0);glVertex3d(x3,y3,z3);
glTexCoord2d(1,1);glVertex3d(x2,y2,z2);
glTexCoord2d(0,1);glVertex3d(x1,y1,z1);
glEnd();

if(mode == GL_SELECT)
glPopName ();
}

glDisable(GL_TEXTURE_2D);
}

Метод рендеринга:

void render()
{
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

glViewport(0,0,this->width() , this->height());

gluPerspective(fov, this->width() / this->height(), 0.1, 1000);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glRotatef(xRot / 5.0f, 1.0f, 0.0f, 0.0f);
glRotatef(yRot / 5.0f, 0.0f, 1.0f, 0.0f);
glRotatef(zRot / 5.0f, 0.0f, 0.0f, 1.0f);

glPushMatrix();
makeCustomAnnot(GL_RENDER);
glPopMatrix();

glDisable(GL_DEPTH_TEST);
}

Так что хиты = glRenderMode (GL_RENDER); всегда возвращает 0 хитов. Что я делаю неправильно?

1

Решение

Вот что я сделал, чтобы все работало идеально.

Метод processHits:

void processHits(GLint inHits, GLuint buffer[])
{
unsigned int i, j;
GLuint names, *ptr, minZ,*ptrNames, numberOfNames;

ptr = (GLuint *) buffer;
minZ = 0xffffffff;
for (i = 0; i < inHits; i++) {
names = *ptr;
ptr++;
if (*ptr < minZ) {
numberOfNames = names;
minZ = *ptr;
ptrNames = ptr+2;
}
ptr += names+2;
}

cout << "Nearest: ";
ptr = ptrNames;
for (j = 0; j < numberOfNames; j++,ptr++) {
cout<< *ptr ;
}
}

Метод рисования объекта с создает объекты, которые мне нужно выбрать:

void makeCustomAnnot(GLenum mode){

glEnable(GL_TEXTURE_2D);
glColor3f(1,1,1);
GLuint j=0;

QImage img("img.jpg");
img=QGLWidget::convertToGLFormat(img);

GLuint texturesAnnot[1];
glBindTexture( GL_TEXTURE_2D, texturesAnnot[0] );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.width(), img.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

if(mode == GL_SELECT)
glLoadName (j);

glBegin(GL_QUADS);
glTexCoord2d(0,0);glVertex3d(x4,y4,z4);
glTexCoord2d(1,0);glVertex3d(x3,y3,z3);
glTexCoord2d(1,1);glVertex3d(x2,y2,z2);
glTexCoord2d(0,1);glVertex3d(x1,y1,z1);
glEnd();

glDisable(GL_TEXTURE_2D);
}

Метод pickObjects, идентичный функции рендеринга, но с инструкциями для выбора:

#define BUFSIZE 512
unsigned int selectBuf[BUFSIZE];

void pickObjects(int x, int y)
{
GLint viewport[4];
GLint hits;

glSelectBuffer (BUFSIZE, selectBuf);
glRenderMode (GL_SELECT);

glMatrixMode (GL_PROJECTION);
glPushMatrix ();
glLoadIdentity ();

glGetIntegerv (GL_VIEWPORT, viewport);

gluPickMatrix ((GLdouble) x, (GLdouble) (viewport[3] - y), 5.0, 5.0, viewport);
gluPerspective(fov, this->width() / this->height(), 0.1, 1000);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

glRotatef(xRot / 5.0f, 1.0f, 0.0f, 0.0f);
glRotatef(yRot / 5.0f, 0.0f, 1.0f, 0.0f);
glRotatef(zRot / 5.0f, 0.0f, 0.0f, 1.0f);

glRotatef((float)angleV, 1.0f, 0.0f, 0.0f);

glInitNames();
glPushName( 10000 );

glPushMatrix();
makeCustomAnnot(GL_SELECT);//draw scene in GL_SELECT mode to create the names
glPopMatrix();

hits = glRenderMode (GL_RENDER);//get the hits in GL_RENDER mode
if (hits != 0)
{
processHits(hits,selectBuf);
}

glPopMatrix();
glDisable(GL_DEPTH_TEST);
}

Метод рендеринга:

void render()
{
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

glViewport(0,0,this->width() , this->height());

gluPerspective(fov, this->width() / this->height(), 0.1, 1000);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glRotatef(xRot / 5.0f, 1.0f, 0.0f, 0.0f);
glRotatef(yRot / 5.0f, 0.0f, 1.0f, 0.0f);
glRotatef(zRot / 5.0f, 0.0f, 0.0f, 1.0f);

glRenderMode (GL_RENDER);

glPushMatrix();
makeCustomAnnot(GL_RENDER);
glPopMatrix();

glDisable(GL_DEPTH_TEST);
}

И, наконец, хиты = glRenderMode (GL_RENDER); в методе pickObjects, а затем метод processHits возвращает именно выбранный объект.

1

Другие решения


По вопросам рекламы [email protected]