PDA

View Full Version : transform feedback does NOT work in Qt



zixuan
25th July 2020, 17:42
I am trying to set up transform feedback on my Qt OpenGL code.

Qt with OpenGL code:

GLfloat vPosition[24] = {
-0.75, -0.25, -0.7, 1.0 ,
-0.25, -0.25, -0.7, 1.0 ,
0.25, 0.25, -0.7, 1.0 ,
0.75, -0.5, -0.8, 1.0 ,
0.0, -0.5, -0.8, 1.0 ,
0.75, 0.5, -0.8, 1.0
};

GLfloat vColor[24] = {
1.0, 0, 0, 1.0 ,
0, 1.0, 0, 1.0 ,
0, 0, 1.0, 1.0 ,
1.0, 1.0, 0, 1.0 ,
0, 1.0, 1.0, 1.0 ,
1.0, 0, 1.0, 1.0
};

GLfloat vMatrix[16] = {
1.0, 0, 0, 0,
0, 1.0, 0, 0,
0, 0, 1.0, 0,
0, 0, 0, 1.0
};

void feedback::initialize() {

initializeShader();

glEnable(GL_DEPTH_TEST);
GLint matrix = glGetUniformLocation(program, "vMatrix");
glUniformMatrix4fv(matrix, 1, GL_TRUE, vMatrix);//second parameter indicates the number of matrices

cf->glGenVertexArrays(2, VAOs);

GLuint vboHandles[2];
glGenBuffers(2, vboHandles);
GLuint positionBufferHandle = vboHandles[0];
GLuint colorBufferHandle = vboHandles[1];

glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);
glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(GLfloat), vPosition, GL_STATIC_DRAW);

glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle);
glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(GLfloat), vColor, GL_STATIC_DRAW);

cf->glBindVertexArray(VAOs[0]);

glEnableVertexAttribArray(0); // Vertex position,
glEnableVertexAttribArray(1);

glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);
glVertexAttribPointer( 0, 4, GL_FLOAT, GL_FALSE, 0, (GLubyte *)NULL );

glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle);
glVertexAttribPointer( 1, 4, GL_FLOAT, GL_FALSE, 0, (GLubyte *)NULL );

// glVertexAttribFormat(position, 4, GL_FLOAT, GL_FALSE, 0);
// glVertexAttribBinding(position, 0);
// glVertexAttribFormat(color, 4, GL_FLOAT, GL_FALSE, 0);
// glVertexAttribBinding(color, 0);
cf->glBindVertexArray(0);

cf->glBindVertexArray(VAOs[1]);

cf->glVertexAttribFormat(0, 4, GL_FLOAT, GL_FALSE, 0);
cf->glVertexAttribBinding(0, 0);
cf->glVertexAttribFormat(1, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GL_FLOAT));
cf->glVertexAttribBinding(1, 0);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
cf->glBindVertexArray(0);

glGenBuffers(2, VBOs);

glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vPosition) + sizeof(vColor), 0, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vPosition), vPosition);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(vPosition), sizeof(vColor), vColor);
glBindBuffer(GL_ARRAY_BUFFER, 0);

glBindBuffer(GL_ARRAY_BUFFER, VBOs[1]);
//glBufferStorage(GL_ARRAY_BUFFER, sizeof(vPosition) + sizeof(vColor), 0, 0);
glBufferData(GL_ARRAY_BUFFER, sizeof(vPosition) + sizeof(vColor), 0, GL_STREAM_READ);
glBindBuffer(GL_ARRAY_BUFFER, 0);

cf->glGenTransformFeedbacks(1, TFBs);

cf->glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, TFBs[0]);
cf->glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, VBOs[1]);
cf->glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);

glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}

void feedback::render() {
m_context->makeCurrent( this );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, this->width() * devicePixelRatio(), this->height() * devicePixelRatio());

float q[48];
glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]);
cf->glGetBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vPosition) + sizeof(vColor), q);

glEnable(GL_RASTERIZER_DISCARD);
cf->glBindVertexArray(VAOs[0]);
cf->glBindVertexBuffer(0, VBOs[0], 0, 4 * sizeof(GL_FLOAT));
cf->glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, TFBs[0]);
cf->glBeginTransformFeedback(GL_TRIANGLES);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDrawArrays(GL_TRIANGLES, 3, 3);
cf->glEndTransformFeedback();
cf->glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
cf->glBindVertexArray(0);

float p[48];
glBindBuffer(GL_ARRAY_BUFFER, VBOs[1]);
cf->glGetBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vPosition) + sizeof(vColor), p);

// print out the content
for (int i = 0; i < 48; i++)
printf("%f\n", p[i]);
printf("\n");

glDisable(GL_RASTERIZER_DISCARD);
cf->glBindVertexArray(VAOs[1]);
cf->glBindVertexBuffer(0, VBOs[1], 0, 8 * sizeof(GL_FLOAT));
cf->glDrawTransformFeedback(GL_TRIANGLES, TFBs[0]);
cf->glBindVertexArray(0);

m_context->swapBuffers( this );
}

This is my Qt code. It is copied almost exactly line by line from a GLEW/GLUT based openGL program that works as expected: two triangles. However, in Qt it does NOT: I only see a black screen. in my code $cf->$ means QOpenGLFunctions_4_5_Core*. When I print out the content obtained from the feedback buffer ("// print out content " in render function) it differs from the same content printed out in the original code using GLEW/GLUT.

I have no real clue why the same code imported to Qt and using QWindow does not work. I guess somehow the creation and display of QWindow object interfere with feedback transformation. BTW, I had similar experience when I reimplement FramebufferObjects in Qt.

zixuan
31st July 2020, 02:22
I found out this out:

The InitializeShaders (which I didn't show), in it I initialized program as an local variable, But program is a global variable.

Silly mistake.