I have an array of IDs for each vertex in my model. I want to render these to a texture so that I can check which vertex was picked in the viewport. My code looks like this
Qt Code:
#include "MyQOpenGLWidget.h" #include <iostream> #include <QToolTip> { m_program = 0; m_fboProgram = 0; m_vertices[0] = -1.0f; m_vertices[1] = 1.0f; m_vertices[2] = -1.0f; m_vertices[3] = 0.95f; m_vertices[4] = -0.95f; m_vertices[5] = 1.0f; m_vertices[6] = 1.0f; m_vertices[7] = 1.0f; m_vertices[8] = 1.0f; m_vertices[9] = 0.95f; m_vertices[10] = 0.95f; m_vertices[11] = 1.0f; m_vertices[12] = 1.0f; m_vertices[13] = -1.0f; m_vertices[14] = 1.0f; m_vertices[15] = -0.95f; m_vertices[16] = 0.95f; m_vertices[17] = -1.0f; m_vertices[18] = -1.0f; m_vertices[19] = -1.0f; m_vertices[20] = -1.0f; m_vertices[21] = -0.95f; m_vertices[22] = -0.95f; m_vertices[23] = -1.0f; m_id[0] = 1; m_id[1] = 2; m_id[2] = 3; m_id[3] = 4; m_id[4] = 5; m_id[5] = 6; m_id[6] = 7; m_id[7] = 8; m_id[8] = 9; m_id[9] = 10; m_id[10] = 11; m_id[11] = 12; } MyQOpenGLWidget::~MyQOpenGLWidget(void) { makeCurrent(); delete m_program; m_vbo.destroy(); m_vao.destroy(); doneCurrent(); } void MyQOpenGLWidget::initializeGL() { initializeOpenGLFunctions(); m_program = new QOpenGLShaderProgram(); m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, "vshader.glsl"); m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, "fshader.glsl"); m_program->link(); m_program->bind(); m_vbo.create(); m_vbo.bind(); m_vbo.setUsagePattern(QOpenGLBuffer::StaticDraw); m_vbo.allocate(m_vertices, sizeof(m_vertices)); m_vao.create(); m_vao.bind(); m_program->enableAttributeArray(0); m_program->setAttributeBuffer(0, GL_FLOAT, 0, 2, 0); m_vao.release(); m_vbo.release(); m_program->release(); m_fboProgram = new QOpenGLShaderProgram(); m_fboProgram->addShaderFromSourceFile(QOpenGLShader::Vertex, "vshaderPicking.glsl"); m_fboProgram->addShaderFromSourceFile(QOpenGLShader::Fragment, "fshaderPicking.glsl"); m_fboProgram->link(); m_fboProgram->bind(); m_vboId.create(); m_vboId.bind(); m_vboId.setUsagePattern(QOpenGLBuffer::StaticDraw); m_vboId.allocate(m_id, sizeof(m_id)); m_vbo.bind(); m_vaoId.create(); m_vaoId.bind(); m_fboProgram->enableAttributeArray(0); m_fboProgram->setAttributeBuffer(0, GL_UNSIGNED_INT, 0, 1, 0); m_fboProgram->enableAttributeArray(1); m_fboProgram->setAttributeBuffer(1, GL_FLOAT, 0, 2, 0); m_vaoId.release(); m_vboId.release(); m_vbo.release(); m_fboProgram->release(); glViewport(0, 0, this->width(), this->height()); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glPointSize(2); glGenTextures(1, &m_idTexture); glBindTexture(GL_TEXTURE_2D, m_idTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, this->width(), this->height(), 0, GL_RED_INTEGER, GL_UNSIGNED_INT, 0); glBindTexture(GL_TEXTURE_2D, 0); glGenTextures(1, &m_depthTexture); glBindTexture(GL_TEXTURE_2D, m_depthTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, this->width(), this->height(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); glBindTexture(GL_TEXTURE_2D, 0); glGenFramebuffers(1, &m_pickingFBO); glBindFramebuffer(GL_FRAMEBUFFER, m_pickingFBO); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_idTexture, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthTexture, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0); } void MyQOpenGLWidget::resizeGL(int w, int h) { glViewport(0, 0, w, h); } void MyQOpenGLWidget::paintGL() { m_program->bind(); { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); m_vao.bind(); glDrawArrays(GL_POINTS, 0, 12); m_vao.release(); } m_program->release(); m_fboProgram->bind(); { glBindFramebuffer(GL_FRAMEBUFFER, m_pickingFBO); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); m_vaoId.bind(); glDrawArrays(GL_POINTS, 0, 12); m_vaoId.release(); GLint* imagen = new GLint[this->width()*this->height()]; memset(imagen, 0, this->width()*this->height()*sizeof(GLint)); glReadPixels(0, 0, this->width(), this->height(), GL_RED_INTEGER, GL_UNSIGNED_INT, imagen); int v; for(auto i = 0; i < this->height(); i++) { for(auto j = 0; j < this->width(); j++) { v = imagen[i*this->width()+j]; std::cout << v << ","; } std::cout << std::endl; } glBindFramebuffer(GL_FRAMEBUFFER, 0); } m_fboProgram->release(); } { QOpenGLWidget::mouseMoveEvent(e); }To copy to clipboard, switch view to plain text mode
and the shaders
Qt Code:
//VERTEX #version 410 layout(location=0) in uint vId; layout(location=1) in vec2 vPosition; flat out uint fId; void main() { gl_Position = vec4(vPosition, 1.0, 1.0); fId = vId; } //FRAGMENT #version 410 flat in uint fId; in vec2 fPosition; out uint fragId; void main() { fragId = fId; }To copy to clipboard, switch view to plain text mode
I can see that there is a number being rendered for each vertex in the model, however, the value of this number is not the IDs corresponding to each vertex. In my example code I expect to have a value betwen 1-12 and the result after reading the texture with glReadPixels(...) looks like
Qt Code:
1048431821,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1048444928,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1048444928,0,0 ,0,0,0,0,0,0,0,0,0,0,0,0,0,To copy to clipboard, switch view to plain text mode
where you can see that the background has a value of 0 and the actual vertices have very big values. Can someone spot any problem in my code? Some suggested that
may be the root of the problems, but then I don't know what to use.Qt Code:
m_fboProgram->enableAttributeArray(0); m_fboProgram->setAttributeBuffer(0, GL_UNSIGNED_INT, 0, 1, 0);To copy to clipboard, switch view to plain text mode
Bookmarks