[Solved] OpenGL discrepancy on Windows and Android
-
Hi,
I'm developing a simple OpenGL app for Android, a Rubik's Cube.
As I had originally started developing it for Windows, I now have it working on both platforms.However, I recently noticed an issue with the rendering, which you can see in the following pictures:
[url=https://dl.dropbox.com/s/snf3y8i37un1idi/Screenshot_2014-08-03-19-36-35.png]Android version[/url]
[url=https://dl.dropbox.com/s/4mw1knztox3jueh/rubiks_bug_01.png]Windows version[/url]
Some parts are lacking in the Android version (as a matter of fact, none of the blue, yellow and orange faces render). It looks like only white, green and red faces can be rendered.Now, I recently changed my rendering code to try and use VBOs properly, and here is the relevant code:
@ // Create buffers
Cell cell;
QList<Cell> cells = m_cube->cells();
std::vector<QVector3D> vertices;
std::vector<QVector3D> colors;
Face face;
QList<Face> faces;
for (int i=0; i<cells.size(); i++)
{
cell = cells.at(i);vertices.clear(); colors.clear(); faces = cell->faces(); for (int j=0; j<faces.size(); j++) { face = faces.at(j); std::vector<QVector3D> faceVertices = face->vertices(); for (unsigned int k=0; k<faceVertices.size(); k++) { vertices.push_back(face->localTransform() * faceVertices.at(k)); colors.push_back(face->colors().at(k)); } } m_vao.append(new QOpenGLVertexArrayObject); m_vao.last()->create(); m_vao.last()->bind(); m_verticesVBO.append(QOpenGLBuffer(QOpenGLBuffer::VertexBuffer)); m_verticesVBO.last().setUsagePattern(QOpenGLBuffer::StaticDraw); m_verticesVBO.last().create(); m_verticesVBO.last().bind(); m_verticesVBO.last().allocate(&vertices[0], vertices.size() * sizeof(QVector3D)); funcs()->glEnableVertexAttribArray(0); funcs()->glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, 0, NULL); m_colorsVBO.append(QOpenGLBuffer(QOpenGLBuffer::VertexBuffer)); m_colorsVBO.last().setUsagePattern(QOpenGLBuffer::StaticDraw); m_colorsVBO.last().create(); m_colorsVBO.last().bind(); m_colorsVBO.last().allocate(&colors[0], colors.size() * sizeof(QVector3D)); funcs()->glEnableVertexAttribArray(1); funcs()->glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, 0, NULL); m_vao.last()->release(); }@
A Cell represents the black blocks that hold the Faces (1, 2 or 3 faces per cell).
For each Cell, I retrieve the Faces' geometry and color, and put them into a new VAO/VBO, with the faces parented to their cells.
As a 3^3 Rubik's Cube has 26 cells, that makes as many VAOs.
The rendering code looks like this:
@ m_program->bind();
computeViewProjectionMatrices();
drawObjects();
m_program->release();// drawObjects()
{
QList<Cell*> cells = m_cube->cells();
QMatrix4x4 matrix;
for (int i=0; i<cells.size(); i++)
{
matrix = m_VPMatrix * cells.at(i)->transform();
m_program->setUniformValue(m_matrixUniform, matrix);m_vao.at(i)->bind(); funcs()->glDrawArrays(GL_TRIANGLES, 0, m_verArray.at(i)); m_vao.at(i)->release(); }
}@
The code I was using previously created and deleted the VAOs/VBOs on the fly during the rendering, effectively using only one, which was obviously wrong.
It did however, display fine on both Windows and Android.Is there anything wrong with my code, or is this a bug/issue on Android, somehow limiting the amount of VAOs/VBOs available?
-
Well, I need a facepalm. Thank you so much for reminding me of this, this is yet another one of my mistakes.
Actually, my previous (wrong) rendering code would create and delete VAOs and VBOs on the fly for each object, and it worked, so I thought I could use VAOs on Android (I had alreay read something about VAOs possibly not working). It probably worked because I would bind the VBOs as well.
When I switched to the proper use of VAOs, I wouldn't bind the VBOs manually anymore, and that's when the issue appeared.To solve this, I simply used a #ifdef Q_OS_ANDROID and bound the VBOs manually again there.
As a result, the rendering now works properly again on both Windows and Android.Thanks!