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


 
					
					 
							
						 
    
    
    
    
    
   
    
    
    
       
    
    
    
    
   Rendered IDs in texture differ from object IDs in program, how come?
 Rendered IDs in texture differ from object IDs in program, how come?
		 
				
				
				
					 Reply With Quote
  Reply With Quote 
			
Bookmarks