PDA

View Full Version : Restart primitive index bug in Xcode?



akilone
06-26-2015, 12:05 PM
Hi everyone,

I started doing project that uses OpenGL on Visual Studio and then I converted to Xcode. Everything works fine, except restart index. Primitives drawing doesn't work as it works on Windows. In VS I used GL_PRIMITIVE_RESTART_FIXED_INDEX to draw many triangle strips in only one call of drawElements, and it worked fine. On Xcode I had to change to glPrimitiveRestart(0xFFFF), because OS X has OpenGL 4.1 which doesn't have GL_PRIMITIVE_RESTART_FIXED_INDEX. And it doesn't draw triangle strips as they are drawn with same code in VS. Triangles are constructed differently, totally messy. I thought that maybe orientation is different (order of vertex specifying for strip). Can that be problem?

As I said, I didn't change code. I construct list of vertices with 0xFFFF element that separate distinct strips. Maybe I'm missing something.

GClements
06-26-2015, 02:53 PM
Did you enable GL_PRIMITIVE_RESTART?

akilone
06-27-2015, 11:53 AM
Yes, I did enable GL_PRIMITIVE_RESTART. It seems that OpenGL draws few triangle strips, but the order and connections are not good, although in VS with GL_PRIMITIVE_RESTART_FIXED_INDEX it works nice.

Alfonse Reinheart
06-27-2015, 05:34 PM
Here's one more possibility. GL_PRIMITIVE_RESTART_FIXED_INDEX uses a fixed index, but that index is not 0xFFFF. It is always the largest possible unsigned integer for whatever index size you're using. So if your draw call looks like glDrawElements(..., GL_UNSIGNED_INT, ...), then the restart index will be 0xFFFFFFFF.

And glPrimitiveRestart takes an unsigned integer index value (the comparison will use a truncated version of what you pass. So if you rendered with unsigned shorts, it will only use the lower 16-bits of that number). So if you pass 0xFFFF, that will not compare equal with 0xFFFFFFFF for unsigned integer indices.

akilone
06-28-2015, 07:20 AM
I use GLushort, and 0xFFF for restart. I didn't mention that I use OpenGL in Qt, maybe that is causing some problems. I wrote function to test this:

void GeometryEngine::drawStrip(QOpenGLShaderProgram* program) {
vector<QVector3D> vertices;
vertices.push_back(QVector3D(0,1,0));
vertices.push_back(QVector3D(0,0,0));
vertices.push_back(QVector3D(1,1,0));
vertices.push_back(QVector3D(1,0,0));
vertices.push_back(QVector3D(0,-1,0));
vertices.push_back(QVector3D(1,-1,0));


size_t numVertices = 6;
size_t numTriangles = 2;

GLushort indices[] = {0,1,2,3, 0xFFFF, 1,4,3,5};


size_t numIndices = 8;

arrayBuf.bind();
arrayBuf.allocate(&vertices[0], numVertices*sizeof(QVector3D));

indexBuf.bind();
indexBuf.allocate(indices, numIndices*sizeof(GLushort));

quintptr offset = 0;

int vertexLocation = program->attributeLocation("a_position");
program->enableAttributeArray(vertexLocation);
program->setAttributeBuffer(vertexLocation, GL_FLOAT, offset, 3, sizeof(QVector3D));

glEnable(GL_PRIMITIVE_RESTART);
glPrimitiveRestartIndex(0xFFFF);

glDrawElements(GL_TRIANGLE_STRIP, numIndices, GL_UNSIGNED_SHORT, 0);

}


Once again, this is working nice in Visual Studio - it draws two quad one a top of another, but in Xcode it gives strange result, triangles of second strip are flipped and it seems like it draws second triangle of first strip as first triangle of second strip, it's very strange result.

Maybe the problem is with version of OpenGL. On windows I have OpenGL 4.3, on Mac there is OpenGL 4.1. I use QOpenGLFunctions from Qt for all of these OpenGL stuff.

akilone
06-28-2015, 08:46 AM
I didn't mention that I use Qt and it's QtOpenGLFunctions. I wrote little function that draws two strips:

void drawStrip(QOpenGLShaderProgram* program) {
vector<QVector3D> vertices;
vertices.push_back(QVector3D(0,1,0));
vertices.push_back(QVector3D(0,0,0));
vertices.push_back(QVector3D(1,1,0));
vertices.push_back(QVector3D(1,0,0));
vertices.push_back(QVector3D(0,-1,0));
vertices.push_back(QVector3D(1,-1,0));

size_t numVertices = 6;
size_t numTriangles = 2;

GLushort indices[] = {0,1,2,3, 0xFFFF, 1,4,3,5};


size_t numIndices = 8;

arrayBuf.bind();
arrayBuf.allocate(&vertices[0], numVertices*sizeof(QVector3D));

indexBuf.bind();
indexBuf.allocate(indices, numIndices*sizeof(GLushort));

quintptr offset = 0;

int vertexLocation = program->attributeLocation("a_position");
program->enableAttributeArray(vertexLocation);
program->setAttributeBuffer(vertexLocation, GL_FLOAT, offset, 3, sizeof(QVector3D));

glEnable(GL_PRIMITIVE_RESTART);
glPrimitiveRestartIndex(0xFFFF);

glDrawElements(GL_TRIANGLE_STRIP, numIndices, GL_UNSIGNED_SHORT, 0);
}

Which should draw two quads one on top of another. It works in VS, as I said, but in Xcode it gives strange result, like it's not restarting indices correctly , 4th triangle is not even drawn and 3th and 4th triangles are flipped.

Maybe, it's a version of OpenGL that cause troubles - in windows is 4.3, and on Mac is 4.1. I tried including QtOpenGLFunctions_4_1_core.h in Xcode, but that won't even compile - it's gives few BAD ACCESS errors. When I include just QtOpenGLFunctions.h, the result is what I described above.