Print3D font vertex and index buffers, WebGL

Hi,

I’m using the PowerVR SDK to work with the .pod and .pfx formats. My rendering engine has a bunch of extra logic built up around it, is written in C++, and runs successfully in iOS, Android, and web. But I’m seeing a problem unique to web when I try to use Print3D. I’ve ported my rendering engine to the web using Emscripten, to keep its logic intact. So, I do realize that this is an issue that probably won’t affect many others. These are the errors I see from Print3D’s Flush method, right at the call to DrawElements:

WebGL: INVALID_OPERATION: vertexAttribPointer: no bound ARRAY_BUFFER
WebGL: INVALID_OPERATION: vertexAttribPointer: no bound ARRAY_BUFFER
WebGL: INVALID_OPERATION: vertexAttribPointer: no bound ARRAY_BUFFER
WebGL: INVALID_OPERATION: drawElements: no ELEMENT_ARRAY_BUFFER bound

After checking the Print3D code, that seems true, no buffers are bound. However, I get no errors in iOS or Android, and I do successfully see the text just as I expect it on those platforms. I also checked the WebGL version of the PowerVR SDK, and in the PVRPrint3D.js Flush method, I’ve noticed this section of code, which doesn’t have a counterpart in the c version of the SDK:

// Upload font data to VBO and IBO
var arrayBufferAsFloat = new Float32Array(this.data.VtxCache);
var indexBufferAsUint16 = new Uint16Array(this.data.fontFaces);

gl.bindBuffer(gl.ARRAY_BUFFER, this.data.APIData.fontVBO);
gl.bufferData(gl.ARRAY_BUFFER, arrayBufferAsFloat, gl.DYNAMIC_DRAW);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.data.APIData.fontIBO);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indexBufferAsUint16, gl.DYNAMIC_DRAW);

So, it appears that WebGL requires that the vertex and index buffers are bound, but other platforms do not. Is that true? Why doesn’t this same code throw errors on iOS and Android? (It seems to me like it should).

I took a stab at adding some code to PVRTPrint3DAPI.cpp to upload the font vbo and ibo data, but I’ve been unsuccessful so far. I’m trying something like this:

if(Data.uFontVbo == UNDEFINED_HANDLE){
glGenBuffers(1, &Data.uFontVbo);
glGenBuffers(1, &Data.uFontIbo);
glBindBuffer(GL_ARRAY_BUFFER, Data.uFontVbo);
glBufferData(GL_ARRAY_BUFFER, m_nVtxCache, &m_pVtxCache[0], GL_DYNAMIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Data.uFontIbo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_nVtxCache, m_pwFacesFont, GL_DYNAMIC_DRAW);
}
glBindBuffer(GL_ARRAY_BUFFER, Data.uFontVbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Data.uFontIbo);

I added those uFontVbo and uFontIbo as part of SPVRTPrint3DAPI::SInstanceData. I know there’s obvious problems in that code snippet above, but it’s not clear to me how to correctly get the font vertex and index buffer data submitted to gl, from the existing objects in the C API. It seems to me like if I can do that, the conversion of my rendering engine to javascript through Emscripten should fix those Print3D WebGL errors I am getting.

Any help that could be offered would be greatly appreciated. Thanks!

Hi Gary, thanks for your feedback. I’ve filed this as a bug for the SDK team to look into. For your reference our internal bug tracker number for this issue is: BRN56434.

For what its worth, I’ve worked around this issue by just using the WebGL javascript version of the PowerVR SDK. In the javascript part of my render loop, I take an extra step and use print3d with the same context that the rest of the scene does. And then inside my emscripten compiled engine I don’t use any Print3d when its running on the web. It’s working well.