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; }
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; }