bool Mesh::load(const char * filename, bool computeTangents) { CTMcontext context = ctmNewContext(CTM_IMPORT); bool result = false; ctmLoad(context, filename); if (ctmGetError(context) == CTM_NONE) { result = true; const CTMuint triangleCount = ctmGetInteger(context, CTM_TRIANGLE_COUNT); const CTMuint vertCount = ctmGetInteger(context, CTM_VERTEX_COUNT); const CTMfloat * vertices = ctmGetFloatArray(context, CTM_VERTICES); const CTMfloat * normals = ctmGetFloatArray(context, CTM_NORMALS); const CTMfloat * texCoord0 = ctmGetFloatArray(context, CTM_UV_MAP_1); const CTMuint * indices = ctmGetIntegerArray(context, CTM_INDICES); begin(); add(Mesh::VERTEX, GL_FLOAT, 3, vertices, sizeof(CTMfloat) * vertCount * 3); add(Mesh::NORMAL, GL_FLOAT, 3, normals, sizeof(CTMfloat) * vertCount * 3); add(Mesh::UV, GL_FLOAT, 3, texCoord0, sizeof(CTMfloat) * vertCount * 2); if (computeTangents) { } add(Mesh::INDICIES, 0, 0, indices, sizeof(CTMuint) * triangleCount); end(triangleCount); } ctmFreeContext(context); return result; }
void LoadMesh() { RenderContext& rc = GlobalRenderContext; // Open the CTM file: CTMcontext ctmContext = ctmNewContext(CTM_IMPORT); ctmLoad(ctmContext, "../demo/HeadlessGiant.ctm"); // PezCheckCondition(ctmGetError(ctmContext) == CTM_NONE, "OpenCTM Issue"); CTMuint vertexCount = ctmGetInteger(ctmContext, CTM_VERTEX_COUNT); rc.IndexCount = 3 * ctmGetInteger(ctmContext, CTM_TRIANGLE_COUNT); GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); // Create the VBO for positions: const CTMfloat* positions = ctmGetFloatArray(ctmContext, CTM_VERTICES); if (positions) { GLuint handle; GLsizeiptr size = vertexCount * sizeof(float) * 3; glGenBuffers(1, &handle); glBindBuffer(GL_ARRAY_BUFFER, handle); glBufferData(GL_ARRAY_BUFFER, size, positions, GL_STATIC_DRAW); glEnableVertexAttribArray(SlotPosition); glVertexAttribPointer(SlotPosition, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, 0); } // Create the VBO for normals: const CTMfloat* normals = ctmGetFloatArray(ctmContext, CTM_NORMALS); if (normals) { GLuint handle; GLsizeiptr size = vertexCount * sizeof(float) * 3; glGenBuffers(1, &handle); glBindBuffer(GL_ARRAY_BUFFER, handle); glBufferData(GL_ARRAY_BUFFER, size, normals, GL_STATIC_DRAW); glEnableVertexAttribArray(SlotNormal); glVertexAttribPointer(SlotNormal, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, 0); } // Create the VBO for indices: const CTMuint* indices = ctmGetIntegerArray(ctmContext, CTM_INDICES); if (indices) { GLuint handle; GLsizeiptr size = rc.IndexCount * sizeof(CTMuint); glGenBuffers(1, &handle); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle); glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, indices, GL_STATIC_DRAW); } ctmFreeContext(ctmContext); }
Mesh CreateMesh(const char* ctmFile, float totalScale, float lengthScale) { Mesh mesh = {0}; char qualifiedPath[256] = {0}; strcpy(qualifiedPath, PezResourcePath()); strcat(qualifiedPath, "/\0"); strcat(qualifiedPath, ctmFile); // Open the CTM file: CTMcontext ctmContext = ctmNewContext(CTM_IMPORT); ctmLoad(ctmContext, qualifiedPath); PezCheckCondition(ctmGetError(ctmContext) == CTM_NONE, "OpenCTM issue with loading %s", qualifiedPath); CTMuint vertexCount = ctmGetInteger(ctmContext, CTM_VERTEX_COUNT); CTMuint faceCount = ctmGetInteger(ctmContext, CTM_TRIANGLE_COUNT); // Create the VBO for positions: const CTMfloat* positions = ctmGetFloatArray(ctmContext, CTM_VERTICES); if (positions) { // Find bounding box float m = 99999.0f; Point3 minCorner = P3MakeFromElems(m, m, m); Point3 maxCorner = P3MakeFromElems(-m, -m, -m); const CTMfloat* pSrc = positions; CTMuint remainingVerts = vertexCount; while (remainingVerts--) { float x = *pSrc++; float y = *pSrc++; float z = *pSrc++; Point3 p = P3MakeFromElems(x, y, z); minCorner = P3MinPerElem(p, minCorner); maxCorner = P3MaxPerElem(p, maxCorner); } // Scale such that the Z extent is 'scale' // The X and Y scales are computed according to the aspect ratio. // The model is centered at (+0.5, +0.5, +0.5). float xratio = (maxCorner.x - minCorner.x) / (maxCorner.z - minCorner.z); float yratio = (maxCorner.y - minCorner.y) / (maxCorner.z - minCorner.z); float sx = lengthScale * totalScale * xratio / (maxCorner.x - minCorner.x); float sy = totalScale * yratio / (maxCorner.y - minCorner.y); float sz = totalScale / (maxCorner.z - minCorner.z); pSrc = positions; remainingVerts = vertexCount; CTMfloat* pDest = (CTMfloat*) positions; while (remainingVerts--) { float x = *pSrc++; float y = *pSrc++; float z = *pSrc++; *pDest++ = (x - minCorner.x) * sx - totalScale * xratio / 2; *pDest++ = (y - minCorner.y) * sy - totalScale * yratio / 2; *pDest++ = (z - minCorner.z) * sz - totalScale / 2; } GLuint handle; GLsizeiptr size = vertexCount * sizeof(float) * 3; glGenBuffers(1, &handle); glBindBuffer(GL_ARRAY_BUFFER, handle); glBufferData(GL_ARRAY_BUFFER, size, positions, GL_STATIC_DRAW); mesh.Positions = handle; } // Create the VBO for normals: const CTMfloat* normals = ctmGetFloatArray(ctmContext, CTM_NORMALS); if (normals) { GLuint handle; GLsizeiptr size = vertexCount * sizeof(float) * 3; glGenBuffers(1, &handle); glBindBuffer(GL_ARRAY_BUFFER, handle); glBufferData(GL_ARRAY_BUFFER, size, normals, GL_STATIC_DRAW); mesh.Normals = handle; } // Create the VBO for indices: const CTMuint* indices = ctmGetIntegerArray(ctmContext, CTM_INDICES); if (indices) { GLsizeiptr bufferSize = faceCount * 3 * sizeof(GLuint); GLuint handle; glGenBuffers(1, &handle); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle); glBufferData(GL_ELEMENT_ARRAY_BUFFER, bufferSize, indices, GL_STATIC_DRAW); mesh.Faces = handle; } ctmFreeContext(ctmContext); mesh.FaceCount = faceCount; mesh.VertexCount = vertexCount; glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); return mesh; }
Mesh CreateMesh(const char* ctmFile) { Mesh mesh = {0, 0, 0, 0}; char qualifiedPath[256] = {0}; strcpy(qualifiedPath, PezResourcePath()); strcat(qualifiedPath, "/\0"); strcat(qualifiedPath, ctmFile); // Open the CTM file: CTMcontext ctmContext = ctmNewContext(CTM_IMPORT); ctmLoad(ctmContext, qualifiedPath); PezCheckCondition(ctmGetError(ctmContext) == CTM_NONE, "OpenCTM issue with loading %s", qualifiedPath); CTMuint vertexCount = ctmGetInteger(ctmContext, CTM_VERTEX_COUNT); CTMuint faceCount = ctmGetInteger(ctmContext, CTM_TRIANGLE_COUNT); // Create the VBO for positions: const CTMfloat* positions = ctmGetFloatArray(ctmContext, CTM_VERTICES); if (positions) { GLuint handle; GLsizeiptr size = vertexCount * sizeof(float) * 3; glGenBuffers(1, &handle); glBindBuffer(GL_ARRAY_BUFFER, handle); glBufferData(GL_ARRAY_BUFFER, size, positions, GL_STATIC_DRAW); mesh.Positions = handle; } // Create the VBO for normals: const CTMfloat* normals = ctmGetFloatArray(ctmContext, CTM_NORMALS); if (normals) { GLuint handle; GLsizeiptr size = vertexCount * sizeof(float) * 3; glGenBuffers(1, &handle); glBindBuffer(GL_ARRAY_BUFFER, handle); glBufferData(GL_ARRAY_BUFFER, size, normals, GL_STATIC_DRAW); mesh.Normals = handle; } // Create the VBO for indices: const CTMuint* indices = ctmGetIntegerArray(ctmContext, CTM_INDICES); if (indices) { GLsizeiptr bufferSize = faceCount * 3 * sizeof(unsigned short); // Convert indices from 32-bit to 16-bit: unsigned short* faceBuffer = (unsigned short*) malloc(bufferSize); unsigned short* pDest = faceBuffer; const CTMuint* pSrc = indices; unsigned int remainingFaces = faceCount; while (remainingFaces--) { *pDest++ = (unsigned short) *pSrc++; *pDest++ = (unsigned short) *pSrc++; *pDest++ = (unsigned short) *pSrc++; } GLuint handle; glGenBuffers(1, &handle); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle); glBufferData(GL_ELEMENT_ARRAY_BUFFER, bufferSize, faceBuffer, GL_STATIC_DRAW); mesh.Faces = handle; free(faceBuffer); } ctmFreeContext(ctmContext); mesh.FaceCount = faceCount; glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); return mesh; }
/* Import OpenCTM file */ int dlImportOCTM( dlObject* object, const char *file, int bAnimated ) { FILE *f; CTMcontext context; CTMuint vertCount, triCount, uvCount, attribCount; const CTMuint *indices; const CTMfloat *vertices, *normals, *coords, *attribs; CTMenum error; unsigned int i, i2; /* the god of iterators, and his child */ const char *textureFilename, *comment, *attribName; char *texturePath = NULL; LOGINFOP("Attempt to load: %s", file); /* obiviously we need a import context * HEY! Maybe CTM_EXPORT would work!? */ context = ctmNewContext( CTM_IMPORT ); /* check if we fail at context creation */ if(!context) { LOGERR("I suck at context creation"); RET("%d", RETURN_FAIL); return( RETURN_FAIL ); } /* Yush! Open the file */ f = fopen( (char*)file, "rb" ); if(!f) { LOGERRP("File: %s, could not open", file); RET("%d", RETURN_FAIL); return( RETURN_FAIL ); } /* I think, i fell love with this API */ ctmLoadCustom( context, (CTMreadfn)readOCTMFile, f ); /* What's the magic word to close it? */ fclose(f); /* lets just hope that it does not have any errors */ if((error = ctmGetError(context)) != CTM_NONE) { /* Go! Pikachu! Use the printf! */ LOGERRP("%s", ctmErrorString( error )); ctmFreeContext(context); RET("%d", RETURN_FAIL); return( RETURN_FAIL ); } /* so far all good, lets do this! */ vertCount = ctmGetInteger( context, CTM_VERTEX_COUNT ); vertices = ctmGetFloatArray( context, CTM_VERTICES ); triCount = ctmGetInteger( context, CTM_TRIANGLE_COUNT ); indices = ctmGetIntegerArray( context, CTM_INDICES ); uvCount = ctmGetInteger( context, CTM_UV_MAP_COUNT ); attribCount = ctmGetInteger( context, CTM_ATTRIB_MAP_COUNT ); comment = ctmGetString( context, CTM_FILE_COMMENT ); if( comment ) dlPuts(comment); /* ok, we go the info.. * now.. how to deal with it? */ dlResetVertexBuffer( object->vbo, vertCount ); dlResetIndexBuffer( object->ibo, triCount * 3 ); /* indices */ i = 0; for(; i != triCount * 3; ++i) dlInsertIndex( object->ibo, indices[i] ); /* vertices */ i = 0; for(; i != vertCount; ++i) dlInsertVertex( object->vbo, vertices[ i * 3 ], vertices[ i * 3 + 1 ], vertices[ i * 3 + 2 ] ); /* texture coords */ i = 0; while( i != uvCount ) { coords = ctmGetFloatArray( context, CTM_UV_MAP_1 + i ); dlResetCoordBuffer( object->vbo, i, vertCount ); /* get texture filename */ textureFilename = ctmGetUVMapString( context, CTM_UV_MAP_1 + i, CTM_FILE_NAME ); if(!textureFilename) textureFilename = ctmGetUVMapString( context, CTM_UV_MAP_1 + i, CTM_NAME ); /* check path */ if(textureFilename) texturePath = dlImportTexturePath( textureFilename, file ); /* load if exists */ if(texturePath) { if(object->material) dlFreeMaterial(object->material); object->material = dlNewMaterialFromImage( texturePath, SOIL_FLAG_DEFAULTS ); free( texturePath ); } i2 = 0; for(; i2 != vertCount; ++i2) { dlInsertCoord( object->vbo, i, coords[ i2 * 2 ], coords[ i2 * 2 + 1 ] ); } ++i; } /* normals */ if(ctmGetInteger(context, CTM_HAS_NORMALS) == CTM_TRUE) { dlResetNormalBuffer( object->vbo, vertCount ); normals = ctmGetFloatArray( context, CTM_NORMALS ); i = 0; for(; i != vertCount; ++i) dlInsertNormal( object->vbo, normals[ i * 3 ], normals[ i * 3 + 1 ], normals[ i * 3 + 2 ] ); } /* custom attribs, only for vertex colors atm */ i = 0; for(; i != attribCount; ++i) { attribName = ctmGetAttribMapString( context, CTM_ATTRIB_MAP_1 + i, CTM_NAME ); attribs = ctmGetFloatArray( context, CTM_ATTRIB_MAP_1 + i ); if(attribName) LOGINFO(attribName); #if VERTEX_COLOR if( strcmp( attribName, COLOR_ATTRIB ) == 0 ) { dlResetColorBuffer( object->vbo, vertCount ); i2 = 0; for(; i2 != vertCount; ++i2) dlInsertColor( object->vbo, attribs[ i2 * 4 ], attribs[ i2 * 4 + 1 ], attribs[ i2 * 4 + 2 ], attribs[ i2 * 4 + 3 ] ); } #endif } /* this is now GL_TRIANGLES object * maybe add tristripper option? */ object->primitive_type = GL_TRIANGLES; /* free the bird */ ctmFreeContext(context); RET("%d", RETURN_OK); return( RETURN_OK ); }
int main(int argc, const char *argv[]) { if(argc != 3) { std::cout << "Usage: #> ./osg_openctm_sqlite inputdb row\n"; std::cout << "* draw an openctm mesh stored as a row in an sqlite db with osg\n"; return 0; } Kompex::SQLiteDatabase *pDatabase = new Kompex::SQLiteDatabase(argv[1],SQLITE_OPEN_READWRITE,0); Kompex::SQLiteStatement *pStmt = new Kompex::SQLiteStatement(pDatabase); int cRow = 0; int rowId = 0; int dbRow = 2; bool isEmpty = false; std::string rowFileKey; pStmt->Sql("SELECT rowid,filekey,empty FROM grid_mesh;"); while(pStmt->FetchRow()) { if(cRow == dbRow) { // row file key rowId = pStmt->GetColumnInt(0); rowFileKey = pStmt->GetColumnString(1); isEmpty = pStmt->GetColumnBool(2); } cRow++; } pStmt->FreeQuery(); Kompex::SQLiteBlob *pKompexBlob; if(!isEmpty) { // read in ctm blob to memory pKompexBlob=new Kompex::SQLiteBlob(pDatabase,"main","grid_mesh","mesh",1); size = pKompexBlob->GetBlobSize(); memblock = new char[size]; pKompexBlob->ReadBlob(memblock,size); delete pKompexBlob; std::cout << "# Read in " << rowFileKey << " (" << size << " bytes)\n"; // uncompress ctm CTMcontext context; CTMuint vertCount, triCount; CTMuint const* indices; CTMfloat const * vertices; context = ctmNewContext(CTM_IMPORT); g_pos = 0; ctmLoadCustom(context,ctmReadBlob,(void*)memblock); if(ctmGetError(context) == CTM_NONE) { // access the mesh data vertCount = ctmGetInteger(context, CTM_VERTEX_COUNT); vertices = ctmGetFloatArray(context, CTM_VERTICES); triCount = ctmGetInteger(context, CTM_TRIANGLE_COUNT); indices = ctmGetIntegerArray(context, CTM_INDICES); std::cout << "# Mesh has " << vertCount << " vertices\n"; std::cout << "# Mesh has " << triCount << " triangles\n"; // build up openscenegraph geometry osg::ref_ptr<osg::Vec3Array> listVxArray = new osg::Vec3Array(vertCount); unsigned int vxIdx=0; for(int i=0; i < listVxArray->size(); i++) { osg::Vec3 vertex; vertex.x() = vertices[vxIdx]; vxIdx++; vertex.y() = vertices[vxIdx]; vxIdx++; vertex.z() = vertices[vxIdx]; vxIdx++; listVxArray->at(i) = vertex; } osg::ref_ptr<osg::DrawElementsUInt> listIdxs = new osg::DrawElementsUInt(GL_TRIANGLES,triCount*3); for(int i=0; i < listIdxs->size(); i++) { listIdxs->at(i) = indices[i]; } osg::ref_ptr<osg::Geometry> geomMesh = new osg::Geometry; geomMesh->setVertexArray(listVxArray.get()); geomMesh->setNormalArray(listVxArray.get()); geomMesh->addPrimitiveSet(listIdxs.get()); osg::ref_ptr<osg::Geode> geodeMesh = new osg::Geode; geodeMesh->addDrawable(geomMesh.get()); osg::ref_ptr<osg::Group> groupRoot = new osg::Group; groupRoot->addChild(geodeMesh.get()); // free ctm memory ctmFreeContext(context); // start viewer osgViewer::Viewer viewer; viewer.setThreadingModel(osgViewer::ViewerBase::SingleThreaded); viewer.setUpViewInWindow(100,100,800,480); viewer.setSceneData(groupRoot.get()); return viewer.run(); } else { std::cout << "# Fatal error reading in mesh file! Exiting...\n"; ctmFreeContext(context); return 0; } // // stuff delete[] memblock; // delete pStmt; // delete pDatabase; return 0; } else { std::cout << "# Row " << rowId << " was empty! Exiting...\n"; delete pStmt; delete pDatabase; return 0; } }
int main(int argc, char *argv[]) { int rc; int exit_application = 0; //Create a screen context that will be used to create an EGL surface to to receive libscreen events screen_create_context(&screen_cxt, 0); //Initialize BPS library bps_initialize(); //Use utility code to initialize EGL for rendering with GL ES 2.0 if (EXIT_SUCCESS != bbutil_init_egl(screen_cxt)) { fprintf(stderr, "bbutil_init_egl failed\n"); bbutil_terminate(); screen_destroy_context(screen_cxt); return 0; } //Initialize application logic osg::setNotifyLevel(osg::DEBUG_INFO); // node: interesting geometry CTMcontext cContext; CTMuint vertCount,triCount; CTMuint const * indices; CTMfloat const * vertices; CTMfloat const * normals; cContext = ctmNewContext(CTM_IMPORT); ctmLoad(cContext,"app/native/models/cow.ctm"); if(ctmGetError(cContext) == CTM_NONE) { // access the mesh data vertCount = ctmGetInteger(cContext, CTM_VERTEX_COUNT); vertices = ctmGetFloatArray(cContext, CTM_VERTICES); triCount = ctmGetInteger(cContext, CTM_TRIANGLE_COUNT); indices = ctmGetIntegerArray(cContext, CTM_INDICES); std::cout << "# Mesh has " << vertCount << " vertices\n"; std::cout << "# Mesh has " << triCount << " triangles\n"; } else { std::cout << "Error Reading CTM File!" << std::endl; return -1; } // build up openscenegraph geometry osg::ref_ptr<osg::Vec3Array> listVxArray = new osg::Vec3Array(vertCount); unsigned int vxIdx=0; for(int i=0; i < listVxArray->size(); i++) { osg::Vec3 vertex; vertex.x() = vertices[vxIdx]; vxIdx++; vertex.y() = vertices[vxIdx]; vxIdx++; vertex.z() = vertices[vxIdx]; vxIdx++; listVxArray->at(i) = vertex; } osg::ref_ptr<osg::DrawElementsUInt> listIdxs = new osg::DrawElementsUInt(GL_TRIANGLES,triCount*3); for(int i=0; i < listIdxs->size(); i++) { listIdxs->at(i) = indices[i]; } osg::ref_ptr<osg::Geometry> geomMesh = new osg::Geometry; geomMesh->setVertexArray(listVxArray.get()); geomMesh->addPrimitiveSet(listIdxs.get()); osgUtil::SmoothingVisitor::smooth(*geomMesh); osg::ref_ptr<osg::Geode> geodeMesh = new osg::Geode; geodeMesh->addDrawable(geomMesh.get()); osg::ref_ptr<osg::Group> groupRoot = new osg::Group; groupRoot->addChild(geodeMesh.get()); // free ctm memory ctmFreeContext(cContext); // shader osg::StateSet *ss = geodeMesh->getOrCreateStateSet(); osg::ref_ptr<osg::Program> program = new osg::Program; program->setName( "simpleshader" ); program->addShader( new osg::Shader( osg::Shader::VERTEX, gVertexShader ) ); program->addShader( new osg::Shader( osg::Shader::FRAGMENT, gFragmentShader ) ); ss->setAttributeAndModes(program, osg::StateAttribute::ON); // ss->setMode(GL_DEPTH_TEST,osg::StateAttribute::ON); // ss->setAttributeAndModes(new osg::CullFace(osg::CullFace::FRONT), osg::StateAttribute::OFF); // ss->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK), osg::StateAttribute::ON); // rotate that cube osg::ref_ptr<osg::MatrixTransform> nodeSpin = new osg::MatrixTransform; nodeSpin->addChild(geodeMesh.get()); nodeSpin->addUpdateCallback(new osg::AnimationPathCallback(osg::Vec3(0,0,0), osg::Y_AXIS, osg::inDegrees(45.0f))); // node: root osg::ref_ptr<osg::Group> nodeRoot = new osg::Group; nodeRoot->addChild(nodeSpin.get()); // center point osg::BoundingBox modelBounds = geodeMesh->getBoundingBox(); // viewer osgViewer::Viewer myViewer; myViewer.setSceneData(nodeRoot.get()); myViewer.getCamera()->setViewMatrixAsLookAt(osg::Vec3((modelBounds.xMax()-modelBounds.xMin())*2, (modelBounds.yMax()-modelBounds.yMin())*2, (modelBounds.zMax()-modelBounds.zMin())*2), modelBounds.center(), osg::Vec3(0,1,0)); // graphics window embedded osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> myWindow = new osgViewer::GraphicsWindowEmbedded(0,0,1024,600); myWindow->getState()->setUseModelViewAndProjectionUniforms(true); myWindow->getState()->setUseVertexAttributeAliasing(true); // setup viewer myViewer.getCamera()->setViewport(new osg::Viewport(0,0,1024,600)); myViewer.getCamera()->setGraphicsContext(myWindow.get()); myViewer.setThreadingModel(osgViewer::Viewer::SingleThreaded); //Signal BPS library that navigator and screen events will be requested if (BPS_SUCCESS != screen_request_events(screen_cxt)) { fprintf(stderr, "screen_request_events failed\n"); bbutil_terminate(); screen_destroy_context(screen_cxt); bps_shutdown(); return 0; } if (BPS_SUCCESS != navigator_request_events(0)) { fprintf(stderr, "navigator_request_events failed\n"); bbutil_terminate(); screen_destroy_context(screen_cxt); bps_shutdown(); return 0; } //Signal BPS library that navigator orientation is not to be locked if (BPS_SUCCESS != navigator_rotation_lock(false)) { fprintf(stderr, "navigator_rotation_lock failed\n"); bbutil_terminate(); screen_destroy_context(screen_cxt); bps_shutdown(); return 0; } while (!exit_application) { //Request and process all available BPS events bps_event_t *event = NULL; for(;;) { rc = bps_get_event(&event, 0); assert(rc == BPS_SUCCESS); if (event) { int domain = bps_event_get_domain(event); if (domain == screen_get_domain()) { handleScreenEvent(event); } else if ((domain == navigator_get_domain()) && (NAVIGATOR_EXIT == bps_event_get_code(event))) { exit_application = 1; } } else { break; } } myViewer.frame(); bbutil_swap(); } //Stop requesting events from libscreen screen_stop_events(screen_cxt); //Shut down BPS library for this process bps_shutdown(); //Use utility code to terminate EGL setup bbutil_terminate(); //Destroy libscreen context screen_destroy_context(screen_cxt); return 0; }