PDA

View Full Version : Rendered IDs in texture differ from object IDs in program, how come?



BRabbit27
2nd September 2015, 18:50
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


#include "MyQOpenGLWidget.h"
#include <iostream>
#include <QToolTip>

MyQOpenGLWidget::MyQOpenGLWidget(QWidget* parent) : QOpenGLWidget(parent)
{
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();
}

void MyQOpenGLWidget::mousePressEvent(QMouseEvent* e)
{
QToolTip::showText(e->globalPos(), QString::number(e->pos().x()) + "," + QString::number(e->pos().x()), this, rect(), 0);
QOpenGLWidget::mouseMoveEvent(e);
}

and the shaders



//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;
}


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



1048431821,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,104844492 8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,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,


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


m_fboProgram->enableAttributeArray(0);
m_fboProgram->setAttributeBuffer(0, GL_UNSIGNED_INT, 0, 1, 0);

may be the root of the problems, but then I don't know what to use.