PDA

View Full Version : picking using VBO



karim
05-31-2011, 10:46 AM
Hello,

I started to develop with Qt and OpenGL. I'm trying to draw polygons using VBO after that i will select one and change his color for example. I drew the polygons but i don't know how to pick one.



myWindow::myWindow(QWidget *parent) :
myGLWidget(60, parent), m_vertexbuffer(QGLBuffer::VertexBuffer),
m_indicebuffer(QGLBuffer::IndexBuffer) {

rotationX = -21.0;
rotationY = -57.0;
rotationZ = 0.0;

for (int i = 0; i <= 4999; i++) {
Rainbow[i] = 0.5f;

}
}

void myWindow::initializeGL() {

qglClearColor(Qt::black);
glShadeModel( GL_FLAT);
glEnable( GL_DEPTH_TEST);
glEnable( GL_CULL_FACE);

vertices_by_x = 4;
vertices_by_y = 2;
quads_by_x = 2;
quads_by_y = 1;

QVector3D vertice;
float cx = -0.5;
float cy = 0.5;

m_vertices.reserve(vertices_by_x * vertices_by_y);
for (int i = 0; i < 24; i++) {
Rainbow[i] = 1.0f;
}

for (int y = 0; y < vertices_by_y; ++y) {
for (int x = 0; x < vertices_by_x; ++x) {

vertice.setX(cx);
vertice.setY(cy);
vertice.setZ(0.0);
m_vertices.push_back(vertice);
cx = cx + 0.4;
}
cx = -0.5;
cy = cy - 0.4;
}

m_indices.reserve(quads_by_x * quads_by_y * 6);

int name=0;
for (int y = 0; y < quads_by_y; ++y) {
int i = 2 * y * vertices_by_x;
for (int x = 0; x < quads_by_x; ++x) {
glLoadName(name);
name++;
m_vertexarray.push_back(m_vertices[i]);
m_vertexarray.push_back(m_vertices[i + vertices_by_x]);
m_vertexarray.push_back(m_vertices[i + 1]);

m_vertexarray.push_back(m_vertices[i + 1]);
m_vertexarray.push_back(m_vertices[i + vertices_by_x]);
m_vertexarray.push_back(m_vertices[i + 1 + vertices_by_x]);

// Indices
m_indices.push_back(i);
m_indices.push_back(i + vertices_by_x);
m_indices.push_back(i + 1);

m_indices.push_back(i + 1);
m_indices.push_back(i + vertices_by_x);
m_indices.push_back(i + 1 + vertices_by_x);

i = i + 2;
}

}

// Vertex buffer init
m_vertexbuffer.create();
m_vertexbuffer.bind();
m_vertexbuffer.allocate(m_vertices.constData(),
m_vertices.size() * sizeof(QVector3D));
m_vertexbuffer.release();

// Indices buffer init
m_indicebuffer.create();
m_indicebuffer.bind();
m_indicebuffer.allocate(m_indices.constData(),
m_indices.size() * sizeof(GLuint));
m_indicebuffer.release();

}

void myWindow::resizeGL(int width, int height) {

glViewport(0, 0, width, height);
glMatrixMode( GL_PROJECTION);
glLoadIdentity();
GLfloat x = GLfloat(width) / height;
glFrustum(-x, x, -1.0, 1.0, 4.0, 15.0);
glMatrixMode( GL_MODELVIEW);

}

void myWindow::paintGL() {

cptPaintGL++;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
draw();
}

void myWindow::draw() {

glMatrixMode( GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -10.0);
glRotatef(rotationX, 1.0, 0.0, 0.0);
glRotatef(rotationY, 0.0, 1.0, 0.0);
glRotatef(rotationZ, 0.0, 0.0, 1.0);

glEnableClientState( GL_VERTEX_ARRAY);
glEnableClientState( GL_COLOR_ARRAY);

m_vertexbuffer.bind();
glVertexPointer(3, GL_FLOAT, 0, NULL);
m_vertexbuffer.release();

glColorPointer(3, GL_FLOAT, 0, Rainbow);

m_indicebuffer.bind();
glDrawElements(GL_TRIANGLES, m_indices.size(), GL_UNSIGNED_INT, NULL);
m_indicebuffer.release();

glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

}



void myWindow::mousePressEvent(QMouseEvent *event) {
lastPos = event->pos();
}
void myWindow::mouseMoveEvent(QMouseEvent *event) {
GLfloat dx = GLfloat(event->x() - lastPos.x()) / width();
GLfloat dy = GLfloat(event->y() - lastPos.y()) / height();

if (event->buttons() & Qt::LeftButton) {
rotationX += 180 * dy;
rotationY += 180 * dx;
updateGL();
} else if (event->buttons() & Qt::RightButton) {
rotationX += 180 * dy;
rotationZ += 180 * dx;
updateGL();
}
lastPos = event->pos();
}

void myWindow::mouseDoubleClickEvent(QMouseEvent *event) {
int face = faceAtPosition(event->pos());
qDebug() << face;
if (face != -1) {
updateGL();
}
}


int myWindow::faceAtPosition(const QPoint &amp;pos) {

const int MaxSize = 512;
GLuint buffer[MaxSize];
GLint viewport[4];

glGetIntegerv(GL_VIEWPORT, viewport);
glSelectBuffer(MaxSize, buffer);
glRenderMode( GL_SELECT);

glInitNames();
glPushName(0);

glMatrixMode( GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPickMatrix(GLdouble(pos.x()), GLdouble(viewport[3] - pos.y()), 5.0, 5.0,
viewport);
GLfloat x = GLfloat(width()) / height();
glFrustum(-x, x, -1.0, 1.0, 4.0, 15.0);
draw();
glMatrixMode(GL_PROJECTION);
glPopMatrix();

if (!glRenderMode(GL_RENDER))
return -1;
return buffer[3];
}

V-man
06-01-2011, 05:35 AM
What I use to do is visualize what gluPickMatrix showed by not going into select mode, just to make sure things were sane.
Also, GL_SELECT mode is ancient. I would suggest
http://www.opengl.org/wiki/Common_Mistakes#Selection_and_Picking_and_Feedback _Mode