void apply_material(const aiMaterial *mtl) { float c[4]; GLenum fill_mode; int ret1, ret2; aiColor4D diffuse; aiColor4D specular; aiColor4D ambient; aiColor4D emission; float shininess, strength; int two_sided; int wireframe; unsigned int max; set_float4(c, 0.8f, 0.8f, 0.8f, 1.0f); if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse)) color4_to_float4(&diffuse, c); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, c); set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f); if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &specular)) color4_to_float4(&specular, c); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c); set_float4(c, 0.2f, 0.2f, 0.2f, 1.0f); if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &ambient)) color4_to_float4(&ambient, c); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, c); set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f); if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &emission)) color4_to_float4(&emission, c); glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, c); max = 1; ret1 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS, &shininess, &max); max = 1; ret2 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS_STRENGTH, &strength, &max); if((ret1 == AI_SUCCESS) && (ret2 == AI_SUCCESS)) glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess * strength); else { glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f); set_float4(c, 0.0f, 0.0f, 0.0f, 0.0f); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c); } max = 1; if(AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_ENABLE_WIREFRAME, &wireframe, &max)) fill_mode = wireframe ? GL_LINE : GL_FILL; else fill_mode = GL_FILL; glPolygonMode(GL_FRONT_AND_BACK, fill_mode); max = 1; if((AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) && two_sided) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); }
static int Texture_mapmode(lua_State *L) { int val; material_t *material = checkmaterial(L, 1); unsigned int type = checktexturetype(L, 2); unsigned int index = checkindex(L, 3); if(aiGetMaterialIntegerArray(material, _AI_MATKEY_MAPPINGMODE_U_BASE, type, index, &val, NULL) != AI_SUCCESS) lua_pushnil(L); else pushtexturemapmode(L, val); if(aiGetMaterialIntegerArray(material, _AI_MATKEY_MAPPINGMODE_V_BASE, type, index, &val, NULL) != AI_SUCCESS) lua_pushnil(L); else pushtexturemapmode(L, val); return 2; }
static int GetInteger(lua_State *L, material_t *material, const char* pKey, unsigned int type, unsigned int index) { int val; if(!material) material = checkmaterial(L, 1); if(aiGetMaterialIntegerArray(material, pKey, type, index, &val, NULL) != AI_SUCCESS) return 0; lua_pushinteger(L, val); return 1; }
static int Shading(lua_State *L) { int val; material_t *material = checkmaterial(L, 1); if(aiGetMaterialIntegerArray(material, AI_MATKEY_SHADING_MODEL, &val, NULL) != AI_SUCCESS) return 0; return pushshadingmode(L, val); }
static int Blend(lua_State *L) { int val; material_t *material = checkmaterial(L, 1); if(aiGetMaterialIntegerArray(material, AI_MATKEY_BLEND_FUNC, &val, NULL) != AI_SUCCESS) return 0; return pushblendmode(L, val); }
static int Texture_flags(lua_State *L) { int val; material_t *material = checkmaterial(L, 1); unsigned int type = checktexturetype(L, 2); unsigned int index = checkindex(L, 3); if(aiGetMaterialIntegerArray(material, _AI_MATKEY_TEXFLAGS_BASE, type, index, &val, NULL) != AI_SUCCESS) val = 0; return pushtextureflags(L, val, 1); }
static int Texture_mapping(lua_State *L) { int val; material_t *material = checkmaterial(L, 1); unsigned int type = checktexturetype(L, 2); unsigned int index = checkindex(L, 3); if(aiGetMaterialIntegerArray(material, _AI_MATKEY_MAPPING_BASE, type, index, &val, NULL) != AI_SUCCESS) return 0; pushtexturemapping(L, val); return 1; }
void createMaterialData( osg::StateSet* ss, const aiMaterial* aiMtl ) const { aiColor4D c; osg::Material* material = new osg::Material; if ( aiGetMaterialColor(aiMtl, AI_MATKEY_COLOR_AMBIENT, &c)==AI_SUCCESS ) material->setAmbient( osg::Material::FRONT_AND_BACK, osg::Vec4(c.r, c.g, c.b, c.a) ); if ( aiGetMaterialColor(aiMtl, AI_MATKEY_COLOR_DIFFUSE, &c)==AI_SUCCESS ) material->setDiffuse( osg::Material::FRONT_AND_BACK, osg::Vec4(c.r, c.g, c.b, c.a) ); if ( aiGetMaterialColor(aiMtl, AI_MATKEY_COLOR_SPECULAR, &c)==AI_SUCCESS ) material->setSpecular( osg::Material::FRONT_AND_BACK, osg::Vec4(c.r, c.g, c.b, c.a) ); if ( aiGetMaterialColor(aiMtl, AI_MATKEY_COLOR_EMISSIVE, &c)==AI_SUCCESS ) material->setEmission( osg::Material::FRONT_AND_BACK, osg::Vec4(c.r, c.g, c.b, c.a) ); unsigned int maxValue = 1; float shininess = 0.0f, strength = 1.0f; if ( aiGetMaterialFloatArray(aiMtl, AI_MATKEY_SHININESS, &shininess, &maxValue)==AI_SUCCESS ) { maxValue = 1; if ( aiGetMaterialFloatArray( aiMtl, AI_MATKEY_SHININESS_STRENGTH, &strength, &maxValue )==AI_SUCCESS ) shininess *= strength; material->setShininess( osg::Material::FRONT_AND_BACK, shininess ); } else { material->setShininess( osg::Material::FRONT_AND_BACK, 0.0f ); material->setSpecular( osg::Material::FRONT_AND_BACK, osg::Vec4() ); } ss->setAttributeAndModes( material ); int wireframe = 0; maxValue = 1; if ( aiGetMaterialIntegerArray(aiMtl, AI_MATKEY_ENABLE_WIREFRAME, &wireframe, &maxValue)==AI_SUCCESS ) { ss->setAttributeAndModes( new osg::PolygonMode( osg::PolygonMode::FRONT_AND_BACK, wireframe ? osg::PolygonMode::LINE : osg::PolygonMode::FILL) ); } }
//------------------------------------------- void ofxAssimpModelLoader::loadGLResources(){ ofLogVerbose("ofxAssimpModelLoader") << "loadGLResources(): starting"; // create new mesh helpers for each mesh, will populate their data later. modelMeshes.resize(scene->mNumMeshes,ofxAssimpMeshHelper()); // create OpenGL buffers and populate them based on each meshes pertinant info. for (unsigned int i = 0; i < scene->mNumMeshes; ++i){ ofLogVerbose("ofxAssimpModelLoader") << "loadGLResources(): loading mesh " << i; // current mesh we are introspecting aiMesh* mesh = scene->mMeshes[i]; // the current meshHelper we will be populating data into. ofxAssimpMeshHelper & meshHelper = modelMeshes[i]; //ofxAssimpMeshHelper meshHelper; //meshHelper.texture = NULL; // Handle material info aiMaterial* mtl = scene->mMaterials[mesh->mMaterialIndex]; aiColor4D dcolor, scolor, acolor, ecolor; if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &dcolor)){ meshHelper.material.setDiffuseColor(aiColorToOfColor(dcolor)); } if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &scolor)){ meshHelper.material.setSpecularColor(aiColorToOfColor(scolor)); } if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &acolor)){ meshHelper.material.setAmbientColor(aiColorToOfColor(acolor)); } if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &ecolor)){ meshHelper.material.setEmissiveColor(aiColorToOfColor(ecolor)); } float shininess; if(AI_SUCCESS == aiGetMaterialFloat(mtl, AI_MATKEY_SHININESS, &shininess)){ meshHelper.material.setShininess(shininess); } int blendMode; if(AI_SUCCESS == aiGetMaterialInteger(mtl, AI_MATKEY_BLEND_FUNC, &blendMode)){ if(blendMode==aiBlendMode_Default){ meshHelper.blendMode=OF_BLENDMODE_ALPHA; }else{ meshHelper.blendMode=OF_BLENDMODE_ADD; } } // Culling unsigned int max = 1; int two_sided; if((AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) && two_sided) meshHelper.twoSided = true; else meshHelper.twoSided = false; // Load Textures int texIndex = 0; aiString texPath; // TODO: handle other aiTextureTypes if(AI_SUCCESS == mtl->GetTexture(aiTextureType_DIFFUSE, texIndex, &texPath)){ ofLogVerbose("ofxAssimpModelLoader") << "loadGLResource(): loading image from \"" << texPath.data << "\""; string modelFolder = file.getEnclosingDirectory(); string relTexPath = ofFilePath::getEnclosingDirectory(texPath.data,false); string texFile = ofFilePath::getFileName(texPath.data); string realPath = ofFilePath::join(ofFilePath::join(modelFolder, relTexPath), texFile); if(ofFile::doesFileExist(realPath) == false) { ofLogError("ofxAssimpModelLoader") << "loadGLResource(): texture doesn't exist: \"" << file.getFileName() + "\" in \"" << realPath << "\""; } ofxAssimpTexture assimpTexture; bool bTextureAlreadyExists = false; for(int j=0; j<textures.size(); j++) { assimpTexture = textures[j]; if(assimpTexture.getTexturePath() == realPath) { bTextureAlreadyExists = true; break; } } if(bTextureAlreadyExists) { meshHelper.assimpTexture = assimpTexture; ofLogVerbose("ofxAssimpModelLoader") << "loadGLResource(): texture already loaded: \"" << file.getFileName() + "\" from \"" << realPath << "\""; } else { ofTexture texture; bool bTextureLoadedOk = ofLoadImage(texture, realPath); if(bTextureLoadedOk) { textures.push_back(ofxAssimpTexture(texture, realPath)); assimpTexture = textures.back(); meshHelper.assimpTexture = assimpTexture; ofLogVerbose("ofxAssimpModelLoader") << "loadGLResource(): texture loaded, dimensions: " << texture.getWidth() << "x" << texture.getHeight(); } else { ofLogError("ofxAssimpModelLoader") << "loadGLResource(): couldn't load texture: \"" << file.getFileName() + "\" from \"" << realPath << "\""; } } } meshHelper.mesh = mesh; aiMeshToOfMesh(mesh, meshHelper.cachedMesh, &meshHelper); meshHelper.cachedMesh.setMode(OF_PRIMITIVE_TRIANGLES); meshHelper.validCache = true; meshHelper.hasChanged = false; meshHelper.animatedPos.resize(mesh->mNumVertices); if(mesh->HasNormals()){ meshHelper.animatedNorm.resize(mesh->mNumVertices); } int usage; if(getAnimationCount()){ #ifndef TARGET_OPENGLES if(!ofIsGLProgrammableRenderer()){ usage = GL_STATIC_DRAW; }else{ usage = GL_STREAM_DRAW; } #else usage = GL_DYNAMIC_DRAW; #endif }else{ usage = GL_STATIC_DRAW; } meshHelper.vbo.setVertexData(&mesh->mVertices[0].x,3,mesh->mNumVertices,usage,sizeof(aiVector3D)); if(mesh->HasVertexColors(0)){ meshHelper.vbo.setColorData(&mesh->mColors[0][0].r,mesh->mNumVertices,GL_STATIC_DRAW,sizeof(aiColor4D)); } if(mesh->HasNormals()){ meshHelper.vbo.setNormalData(&mesh->mNormals[0].x,mesh->mNumVertices,usage,sizeof(aiVector3D)); } if (meshHelper.cachedMesh.hasTexCoords()){ meshHelper.vbo.setTexCoordData(meshHelper.cachedMesh.getTexCoordsPointer()[0].getPtr(),mesh->mNumVertices,GL_STATIC_DRAW,sizeof(ofVec2f)); } meshHelper.indices.resize(mesh->mNumFaces * 3); int j=0; for (unsigned int x = 0; x < mesh->mNumFaces; ++x){ for (unsigned int a = 0; a < mesh->mFaces[x].mNumIndices; ++a){ meshHelper.indices[j++]=mesh->mFaces[x].mIndices[a]; } } meshHelper.vbo.setIndexData(&meshHelper.indices[0],meshHelper.indices.size(),GL_STATIC_DRAW); //modelMeshes.push_back(meshHelper); } int numOfAnimations = scene->mNumAnimations; for(int i=0; i<numOfAnimations; i++) { aiAnimation * animation = scene->mAnimations[i]; animations.push_back(ofxAssimpAnimation(scene, animation)); } ofLogVerbose("ofxAssimpModelLoader") << "loadGLResource(): finished"; }
void apply_material(const struct aiMaterial *mtl) { float c[4]; GLenum fill_mode; int ret1, ret2; struct aiColor4D diffuse; struct aiColor4D specular; struct aiColor4D ambient; struct aiColor4D emission; float shininess, strength; int two_sided; int wireframe; int max; int texIndex = 0; aiString texPath; //contains filename of texture if(AI_SUCCESS == mtl->GetTexture(aiTextureType_DIFFUSE, texIndex, &texPath)) { //bind texture unsigned int texId = *textureIdMap[texPath.data]; glBindTexture(GL_TEXTURE_2D, texId); } set_float4(c, 0.8f, 0.8f, 0.8f, 1.0f); if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse)) color4_to_float4(&diffuse, c); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, c); set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f); if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &specular)) color4_to_float4(&specular, c); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c); set_float4(c, 0.2f, 0.2f, 0.2f, 1.0f); if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &ambient)) color4_to_float4(&ambient, c); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, c); set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f); if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &emission)) color4_to_float4(&emission, c); glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, c); max = 1; ret1 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS, &shininess, (unsigned int *)&max); max = 1; ret2 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS_STRENGTH, &strength, (unsigned int *)&max); if((ret1 == AI_SUCCESS) && (ret2 == AI_SUCCESS)) glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess * strength); else { glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f); set_float4(c, 0.0f, 0.0f, 0.0f, 0.0f); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c); } max = 1; if(AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_ENABLE_WIREFRAME, &wireframe, (unsigned int *)&max)) fill_mode = wireframe ? GL_LINE : GL_FILL; else fill_mode = GL_FILL; glPolygonMode(GL_FRONT_AND_BACK, fill_mode); max = 1; if((AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_TWOSIDED, &two_sided, (unsigned int *)&max)) && two_sided) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); }
static int PushTexture(lua_State *L, material_t *material, unsigned int type, unsigned int index) /* Pushes a table with all the texture properties */ { int val; float floatval; vector3_t vec; struct aiUVTransform trafo; unsigned int max = sizeof(vector3_t); lua_newtable(L); pushtexturetype(L, type); lua_setfield(L, -2, "type"); if(aiGetMaterialIntegerArray(material, _AI_MATKEY_TEXFLAGS_BASE, type, index, &val, NULL) != AI_SUCCESS) val = 0; pushtextureflags(L, val, 1); lua_setfield(L, -2, "flags"); if(GetString(L, material, _AI_MATKEY_TEXTURE_BASE, type, index)==1) lua_setfield(L, -2, "path"); if(aiGetMaterialIntegerArray(material, _AI_MATKEY_UVWSRC_BASE, type, index, &val, NULL) == AI_SUCCESS) { pushindex(L, val); lua_setfield(L, -2, "channel"); } if(aiGetMaterialIntegerArray(material, _AI_MATKEY_TEXOP_BASE, type, index, &val, NULL) == AI_SUCCESS) { pushtextureop(L, val); lua_setfield(L, -2, "op"); } if(aiGetMaterialIntegerArray(material, _AI_MATKEY_MAPPING_BASE, type, index, &val, NULL) == AI_SUCCESS) { pushtexturemapping(L, val); lua_setfield(L, -2, "mapping"); } if(aiGetMaterialFloatArray(material, _AI_MATKEY_TEXBLEND_BASE, type, index, &floatval, NULL) == AI_SUCCESS) { lua_pushnumber(L, floatval); lua_setfield(L, -2, "blend"); } if(aiGetMaterialIntegerArray(material, _AI_MATKEY_MAPPINGMODE_U_BASE, type, index, &val, NULL) == AI_SUCCESS) { pushtexturemapmode(L, val); lua_setfield(L, -2, "mapmode_u"); } if(aiGetMaterialIntegerArray(material, _AI_MATKEY_MAPPINGMODE_V_BASE, type, index, &val, NULL) == AI_SUCCESS) { pushtexturemapmode(L, val); lua_setfield(L, -2, "mapmode_v"); } max = sizeof(vector3_t); if(AI_SUCCESS == aiGetMaterialFloatArray(material, _AI_MATKEY_TEXMAP_AXIS_BASE, type, index, (float*)&vec, &max) && sizeof(vector3_t) == max) { pushvector3(L, &vec, 1); lua_setfield(L, -2, "axis"); } max = sizeof(struct aiUVTransform); if(AI_SUCCESS == aiGetMaterialFloatArray(material, _AI_MATKEY_UVTRANSFORM_BASE, type, index, (float*)&trafo, &max) && sizeof(struct aiUVTransform) == max) { pushvector2(L, &(trafo.mTranslation), 1); lua_setfield(L, -2, "translation"); pushvector2(L, &(trafo.mScaling), 1); lua_setfield(L, -2, "scaling"); lua_pushnumber(L, trafo.mRotation); lua_setfield(L, -2, "rotation"); } return 1; }
//------------------------------------------- void ofxAssimpModelLoader::loadGLResources(){ ofLog(OF_LOG_VERBOSE, "loading gl resources"); // create new mesh helpers for each mesh, will populate their data later. // modelMeshes.resize(scene->mNumMeshes,ofxAssimpMeshHelper()); // create OpenGL buffers and populate them based on each meshes pertinant info. for (unsigned int i = 0; i < scene->mNumMeshes; ++i){ ofLog(OF_LOG_VERBOSE, "loading mesh %u", i); // current mesh we are introspecting aiMesh* mesh = scene->mMeshes[i]; // the current meshHelper we will be populating data into. //ofxAssimpMeshHelper & meshHelper = modelMeshes[i]; ofxAssimpMeshHelper meshHelper; //meshHelper.texture = NULL; // Handle material info aiMaterial* mtl = scene->mMaterials[mesh->mMaterialIndex]; aiColor4D dcolor, scolor, acolor, ecolor; if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &dcolor)){ meshHelper.material.setDiffuseColor(aiColorToOfColor(dcolor)); } if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &scolor)){ meshHelper.material.setSpecularColor(aiColorToOfColor(scolor)); } if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &acolor)){ meshHelper.material.setAmbientColor(aiColorToOfColor(acolor)); } if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &ecolor)){ meshHelper.material.setEmissiveColor(aiColorToOfColor(ecolor)); } float shininess; if(AI_SUCCESS == aiGetMaterialFloat(mtl, AI_MATKEY_SHININESS, &shininess)){ meshHelper.material.setShininess(shininess); } int blendMode; if(AI_SUCCESS == aiGetMaterialInteger(mtl, AI_MATKEY_BLEND_FUNC, &blendMode)){ if(blendMode==aiBlendMode_Default){ meshHelper.blendMode=OF_BLENDMODE_ALPHA; }else{ meshHelper.blendMode=OF_BLENDMODE_ADD; } } // Culling unsigned int max = 1; int two_sided; if((AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) && two_sided) meshHelper.twoSided = true; else meshHelper.twoSided = false; // Load Textures int texIndex = 0; aiString texPath; // TODO: handle other aiTextureTypes if(AI_SUCCESS == mtl->GetTexture(aiTextureType_DIFFUSE, texIndex, &texPath)){ ofLog(OF_LOG_VERBOSE, "loading image from %s", texPath.data); string modelFolder = ofFilePath::getEnclosingDirectory(filepath,false); string relTexPath = ofFilePath::getEnclosingDirectory(texPath.data,false); string texFile = ofFilePath::getFileName(texPath.data); string realPath = modelFolder + relTexPath + texFile; if(!ofFile::doesFileExist(realPath) || !ofLoadImage(meshHelper.texture,realPath)) { ofLog(OF_LOG_ERROR,string("error loading image ") + filepath + " " +realPath); }else{ ofLog(OF_LOG_VERBOSE, "texture width: %f height %f", meshHelper.texture.getWidth(), meshHelper.texture.getHeight()); } } meshHelper.mesh = mesh; aiMeshToOfMesh(mesh, meshHelper.cachedMesh, &meshHelper); meshHelper.cachedMesh.setMode(OF_PRIMITIVE_TRIANGLES); meshHelper.validCache = true; meshHelper.hasChanged = false; meshHelper.animatedPos.resize(mesh->mNumVertices); if(mesh->HasNormals()){ meshHelper.animatedNorm.resize(mesh->mNumVertices); } int usage; if(getAnimationCount()){ #ifndef TARGET_OPENGLES usage = GL_STREAM_DRAW; #else usage = GL_DYNAMIC_DRAW; #endif }else{ usage = GL_STATIC_DRAW; } meshHelper.vbo.setVertexData(&mesh->mVertices[0].x,3,mesh->mNumVertices,usage,sizeof(aiVector3D)); if(mesh->HasVertexColors(0)){ meshHelper.vbo.setColorData(&mesh->mColors[0][0].r,mesh->mNumVertices,GL_STATIC_DRAW,sizeof(aiColor4D)); } if(mesh->HasNormals()){ meshHelper.vbo.setNormalData(&mesh->mNormals[0].x,mesh->mNumVertices,usage,sizeof(aiVector3D)); } if (meshHelper.cachedMesh.hasTexCoords()){ meshHelper.vbo.setTexCoordData(meshHelper.cachedMesh.getTexCoordsPointer()[0].getPtr(),mesh->mNumVertices,GL_STATIC_DRAW,sizeof(ofVec2f)); } meshHelper.indices.resize(mesh->mNumFaces * 3); int j=0; for (unsigned int x = 0; x < mesh->mNumFaces; ++x){ for (unsigned int a = 0; a < mesh->mFaces[x].mNumIndices; ++a){ meshHelper.indices[j++]=mesh->mFaces[x].mIndices[a]; } } meshHelper.vbo.setIndexData(&meshHelper.indices[0],meshHelper.indices.size(),GL_STATIC_DRAW); modelMeshes.push_back(meshHelper); } animationTime = -1; setNormalizedTime(0); ofLog(OF_LOG_VERBOSE, "finished loading gl resources"); }
//------------------------------------------- void ofxAssimpModelLoader::loadGLResources(){ ofLog(OF_LOG_VERBOSE, "loading gl resources"); // create new mesh helpers for each mesh, will populate their data later. modelMeshes.reserve(scene->mNumMeshes); // create OpenGL buffers and populate them based on each meshes pertinant info. for (unsigned int i = 0; i < scene->mNumMeshes; ++i){ ofLog(OF_LOG_VERBOSE, "loading mesh %u", i); // current mesh we are introspecting aiMesh* mesh = scene->mMeshes[i]; // the current meshHelper we will be populating data into. ofxAssimpMeshHelper meshHelper; meshHelper.mesh = mesh; // set the mesh's default values. aiColor4D dcolor = aiColor4D(0.8f, 0.8f, 0.8f, 1.0f); meshHelper.diffuseColor = dcolor; aiColor4D scolor = aiColor4D(0.0f, 0.0f, 0.0f, 1.0f); meshHelper.specularColor = scolor; aiColor4D acolor = aiColor4D(0.2f, 0.2f, 0.2f, 1.0f); meshHelper.ambientColor = acolor; aiColor4D ecolor = aiColor4D(0.0f, 0.0f, 0.0f, 1.0f); meshHelper.emissiveColor = ecolor; // Handle material info aiMaterial* mtl = scene->mMaterials[mesh->mMaterialIndex]; // Load Textures int texIndex = 0; aiString texPath; //meshHelper.texture = NULL; // TODO: handle other aiTextureTypes if(AI_SUCCESS == mtl->GetTexture(aiTextureType_DIFFUSE, texIndex, &texPath)){ // This is magic. Thanks Kyle. textures.push_back(ofImage()); ofImage& image = textures.back(); ofLog(OF_LOG_VERBOSE, "loading image from %s", texPath.data); image.loadImage(texPath.data); image.update(); ofLog(OF_LOG_VERBOSE, "texture width: %f height %f", image.getWidth(), image.getHeight()); //meshHelper.texture = &(image.getTextureReference()); meshHelper.textureIndex = textures.size()-1; } if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &dcolor)) meshHelper.diffuseColor = dcolor; if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &scolor)) meshHelper.specularColor = scolor; if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &acolor)) meshHelper.ambientColor = acolor; if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &ecolor)) meshHelper.emissiveColor = ecolor; // Culling unsigned int max = 1; int two_sided; if((AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) && two_sided) meshHelper.twoSided = true; else meshHelper.twoSided = false; // Create a VBO for our vertices GLuint vhandle; glGenBuffers(1, &vhandle); glBindBuffer(GL_ARRAY_BUFFER, vhandle); if(getAnimationCount()) glBufferData(GL_ARRAY_BUFFER, sizeof(aiVertex) * mesh->mNumVertices, NULL, GL_STREAM_DRAW/*GL_STATIC_DRAW GL_STREAM_DRAW*/); else glBufferData(GL_ARRAY_BUFFER, sizeof(aiVertex) * mesh->mNumVertices, NULL, GL_STATIC_DRAW/*GL_STATIC_DRAW GL_STREAM_DRAW*/); // populate vertices aiVertex* verts = (aiVertex*)glMapBuffer(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); for (unsigned int x = 0; x < mesh->mNumVertices; ++x) { verts->vPosition = mesh->mVertices[x]; if (NULL == mesh->mNormals) verts->vNormal = aiVector3D(0.0f,0.0f,0.0f); else verts->vNormal = mesh->mNormals[x]; if (mesh->HasVertexColors(0)) { verts->dColorDiffuse = mesh->mColors[0][x]; } else verts->dColorDiffuse = aiColor4D(1.0, 1.0, 1.0, 1.0); // This varies slightly form Assimp View, we support the 3rd texture component. if (mesh->HasTextureCoords(0)) verts->vTextureUV = mesh->mTextureCoords[0][x]; else verts->vTextureUV = aiVector3D(0.5f,0.5f, 0.0f); // No longer in aiVertex VBO structure /* if (NULL == mesh->mTangents) { verts->vTangent = aiVector3D(0.0f,0.0f,0.0f); verts->vBitangent = aiVector3D(0.0f,0.0f,0.0f); } else { verts->vTangent = mesh->mTangents[x]; verts->vBitangent = mesh->mBitangents[x]; } if (mesh->HasTextureCoords(1)) verts->vTextureUV2 = mesh->mTextureCoords[1][x]; else verts->vTextureUV2 = aiVector3D(0.5f,0.5f, 0.0f); if( mesh->HasBones()){ unsigned char boneIndices[4] = { 0, 0, 0, 0 }; unsigned char boneWeights[4] = { 0, 0, 0, 0 }; ai_assert( weightsPerVertex[x].size() <= 4); for( unsigned int a = 0; a < weightsPerVertex[x].size(); a++){ boneIndices[a] = weightsPerVertex[x][a].mVertexId; boneWeights[a] = (unsigned char) (weightsPerVertex[x][a].mWeight * 255.0f); } memcpy( verts->mBoneIndices, boneIndices, sizeof( boneIndices)); memcpy( verts->mBoneWeights, boneWeights, sizeof( boneWeights)); } else{ // memset( verts->mBoneIndices, 0, sizeof( verts->mBoneIndices)); // memset( verts->mBoneWeights, 0, sizeof( verts->mBoneWeights)); } */ ++verts; } glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); //invalidates verts glBindBuffer(GL_ARRAY_BUFFER, 0); // set the mesh vertex buffer handle to our new vertex buffer. meshHelper.vertexBuffer = vhandle; // Create Index Buffer unsigned int nidx; switch (mesh->mPrimitiveTypes){ case aiPrimitiveType_POINT: nidx = 1;break; case aiPrimitiveType_LINE: nidx = 2;break; case aiPrimitiveType_TRIANGLE: nidx = 3;break; default: assert(false); } GLuint ihandle; glGenBuffers(1, &ihandle); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ihandle); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * mesh->mNumFaces * nidx, NULL, GL_STATIC_DRAW/*GL_STATIC_DRAW GL_STREAM_DRAW*/); unsigned int* indices = (unsigned int*)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY_ARB); // now fill the index buffer for (unsigned int x = 0; x < mesh->mNumFaces; ++x){ for (unsigned int a = 0; a < nidx; ++a){ *indices++ = mesh->mFaces[x].mIndices[a]; } } glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // set the mesh index buffer handle to our new index buffer. meshHelper.indexBuffer = ihandle; meshHelper.numIndices = mesh->mNumFaces * nidx; // create the normal buffer. Assimp View creates a second normal buffer. Unsure why. Using only the interleaved normals for now. // This is here for reference. /* GLuint nhandle; glGenBuffers(1, &nhandle); glBindBuffer(GL_ARRAY_BUFFER, nhandle); glBufferData(GL_ARRAY_BUFFER, sizeof(aiVector3D)* mesh->mNumVertices, NULL, GL_STATIC_DRAW); // populate normals aiVector3D* normals = (aiVector3D*)glMapBuffer(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); for (unsigned int x = 0; x < mesh->mNumVertices; ++x) { aiVector3D vNormal = mesh->mNormals[x]; *normals = vNormal; ++normals; } glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); //invalidates verts glBindBuffer(GL_ARRAY_BUFFER, 0); meshHelper.normalBuffer = nhandle; */ // Create VAO and populate it GLuint vaoHandle; glGenVertexArraysAPPLE(1, &vaoHandle); // TODO: equivalent PC call. glBindVertexArrayAPPLE(vaoHandle); glBindBuffer(GL_ARRAY_BUFFER, meshHelper.vertexBuffer); glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(GL_FLOAT, sizeof(aiVertex), BUFFER_OFFSET(12)); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(3, GL_FLOAT, sizeof(aiVertex), BUFFER_OFFSET(24)); //TODO: handle second texture glEnableClientState(GL_COLOR_ARRAY); glColorPointer(4, GL_FLOAT, sizeof(aiVertex), BUFFER_OFFSET(36)); // VertexPointer ought to come last, apparently this is some optimization, since if its set once first, it gets fiddled with every time something else is update. glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, sizeof(aiVertex), 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshHelper.indexBuffer); glBindVertexArrayAPPLE(0); // save the VAO handle into our mesh helper meshHelper.vao = vaoHandle; modelMeshes.push_back(meshHelper); } ofLog(OF_LOG_VERBOSE, "finished loading gl resources"); }
void CGLView::Material_Apply(const aiMaterial* pMaterial) { GLfloat tcol[4]; aiColor4D taicol; unsigned int max; int ret1, ret2; int texture_index = 0; aiString texture_path; auto set_float4 = [](float f[4], float a, float b, float c, float d) { f[0] = a, f[1] = b, f[2] = c, f[3] = d; }; auto color4_to_float4 = [](const aiColor4D *c, float f[4]) { f[0] = c->r, f[1] = c->g, f[2] = c->b, f[3] = c->a; }; ///TODO: cache materials // Disable color material because glMaterial is used. glDisable(GL_COLOR_MATERIAL);///TODO: cache // Set texture. If assigned. if(AI_SUCCESS == pMaterial->GetTexture(aiTextureType_DIFFUSE, texture_index, &texture_path)) { //bind texture unsigned int texture_ID = mTexture_IDMap.value(texture_path.data, 0); glBindTexture(GL_TEXTURE_2D, texture_ID); } // // Set material parameters from scene or default values. // // Diffuse set_float4(tcol, 0.8f, 0.8f, 0.8f, 1.0f); if(AI_SUCCESS == aiGetMaterialColor(pMaterial, AI_MATKEY_COLOR_DIFFUSE, &taicol)) color4_to_float4(&taicol, tcol); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, tcol); // Specular set_float4(tcol, 0.0f, 0.0f, 0.0f, 1.0f); if(AI_SUCCESS == aiGetMaterialColor(pMaterial, AI_MATKEY_COLOR_SPECULAR, &taicol)) color4_to_float4(&taicol, tcol); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, tcol); // Ambient set_float4(tcol, 0.2f, 0.2f, 0.2f, 1.0f); if(AI_SUCCESS == aiGetMaterialColor(pMaterial, AI_MATKEY_COLOR_AMBIENT, &taicol)) color4_to_float4(&taicol, tcol); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, tcol); // Emission set_float4(tcol, 0.0f, 0.0f, 0.0f, 1.0f); if(AI_SUCCESS == aiGetMaterialColor(pMaterial, AI_MATKEY_COLOR_EMISSIVE, &taicol)) color4_to_float4(&taicol, tcol); glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, tcol); // Shininess float shininess, strength; max = 1; ret1 = aiGetMaterialFloatArray(pMaterial, AI_MATKEY_SHININESS, &shininess, &max); // Shininess strength max = 1; ret2 = aiGetMaterialFloatArray(pMaterial, AI_MATKEY_SHININESS_STRENGTH, &strength, &max); if((ret1 == AI_SUCCESS) && (ret2 == AI_SUCCESS)) { glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess * strength);///TODO: cache } else { glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f);///TODO: cache set_float4(tcol, 0.0f, 0.0f, 0.0f, 0.0f); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, tcol); } // Fill mode GLenum fill_mode; int wireframe; max = 1; if(AI_SUCCESS == aiGetMaterialIntegerArray(pMaterial, AI_MATKEY_ENABLE_WIREFRAME, &wireframe, &max)) fill_mode = wireframe ? GL_LINE : GL_FILL; else fill_mode = GL_FILL; glPolygonMode(GL_FRONT_AND_BACK, fill_mode);///TODO: cache // Fill side int two_sided; max = 1; if((AI_SUCCESS == aiGetMaterialIntegerArray(pMaterial, AI_MATKEY_TWOSIDED, &two_sided, &max)) && two_sided)///TODO: cache glDisable(GL_CULL_FACE); else glEnable(GL_CULL_FACE); }
void AssimpModel::applyMaterial(const aiMaterial *mtl) { int texIndex = 0; aiString texPath; //contains filename of texture if(AI_SUCCESS == mtl->GetTexture(aiTextureType_DIFFUSE, texIndex, &texPath)) { GLuint& texId = m_textures[texPath.data]; glBindTexture(GL_TEXTURE_2D, texId); } float color[4]; set_float4(color, 0.8f, 0.8f, 0.8f, 1.0f); aiColor4D diffuse; if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse)) color4_to_float4(&diffuse, color); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color); set_float4(color, 0.0f, 0.0f, 0.0f, 1.0f); aiColor4D specular; if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &specular)) color4_to_float4(&specular, color); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color); set_float4(color, 0.2f, 0.2f, 0.2f, 1.0f); aiColor4D ambient; if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &ambient)) color4_to_float4(&ambient, color); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color); set_float4(color, 0.0f, 0.0f, 0.0f, 1.0f); aiColor4D emission; if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &emission)) color4_to_float4(&emission, color); glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color); float shininess, strength; unsigned int max = 1; if( aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS, &shininess, &max) == AI_SUCCESS && aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS_STRENGTH, &strength, &max) == AI_SUCCESS) glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess * strength); else { glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f); set_float4(color, 0.0f, 0.0f, 0.0f, 0.0f); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color); } max = 1; GLenum fill_mode; int wireframe; if(AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_ENABLE_WIREFRAME, &wireframe, &max)) { fill_mode = wireframe ? GL_LINE : GL_FILL; } else { fill_mode = GL_FILL; } glPolygonMode(GL_FRONT_AND_BACK, fill_mode); max = 1; int two_sided; if((AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) && two_sided) { glEnable(GL_CULL_FACE); } else { glDisable(GL_CULL_FACE); } }
//////////////////////////////////////////////////////////////////////// /// /// @fn void Modele3D::appliquerMateriau( const aiMaterial* materiau ) /// /// Cette fonction applique un matériau 'assimp' à l'état OpenGL /// courant (puisque certains meshes peuvent en dépendre). Le code est /// chaotique; rassurons-nous cette fonction ne fait qu'effectuer /// des appels OpenGL selon l'état de la structure interne du matériau /// 'assimp' ainsi que quelques calculs. /// /// @param[in] materiau : matériau 'assimp' à appliquer /// /// @return Aucune. /// //////////////////////////////////////////////////////////////////////// void Modele3D::appliquerMateriau(const aiMaterial* materiau) { // Obtenir la texture du matériau int indexTexture = 0; aiString nomFichier = ""; glMatrixMode(GL_TEXTURE); glPushMatrix(); if (materiau->GetTexture(aiTextureType_DIFFUSE, indexTexture, &nomFichier) == AI_SUCCESS) { // Activer le texturage OpenGL et lier la texture appropriée glEnable ( GL_TEXTURE_2D); GLuint* idTexture = mapTextures_[nomFichier.data]; glScalef(1.0,-1.0,1.0); glBindTexture(GL_TEXTURE_2D, *idTexture); } else { // Désactiver le texturage OpenGL puisque cet objet n'a aucune texture glDisable ( GL_TEXTURE_2D); } glMatrixMode(GL_MODELVIEW); // Autres paramètres à appliquer... (couleurs) float c[4]; GLenum fill_mode; int ret1, ret2; struct aiColor4D diffuse; struct aiColor4D specular; struct aiColor4D ambient; struct aiColor4D emission; float shininess, strength; int two_sided; int wireframe; unsigned int max; // changé pour: unsigned assignerFloat4(c, 0.8f, 0.8f, 0.8f, 1.0f); //assignerFloat4(c, 1.0f, 1.0f, 1.0f, 1.0f); if (aiGetMaterialColor(materiau, AI_MATKEY_COLOR_DIFFUSE, &diffuse) == AI_SUCCESS) couleurVersFloat4(&diffuse, c); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, c); assignerFloat4(c, 0.0f, 0.0f, 0.0f, 1.0f); if(AI_SUCCESS == aiGetMaterialColor(materiau, AI_MATKEY_COLOR_SPECULAR, &specular)) couleurVersFloat4(&specular, c); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c); assignerFloat4(c, 0.2f, 0.2f, 0.2f, 1.0f); if(AI_SUCCESS == aiGetMaterialColor(materiau, AI_MATKEY_COLOR_AMBIENT, &ambient)) couleurVersFloat4(&ambient, c); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, c); assignerFloat4(c, 0.0f, 0.0f, 0.0f, 1.0f); if(AI_SUCCESS == aiGetMaterialColor(materiau, AI_MATKEY_COLOR_EMISSIVE, &emission)) couleurVersFloat4(&emission, c); glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, c); max = 1; ret1 = aiGetMaterialFloatArray(materiau, AI_MATKEY_SHININESS, &shininess, &max); max = 1; ret2 = aiGetMaterialFloatArray(materiau, AI_MATKEY_SHININESS_STRENGTH, &strength, &max); if((ret1 == AI_SUCCESS) && (ret2 == AI_SUCCESS)) glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess * strength); else { glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f); assignerFloat4(c, 0.0f, 0.0f, 0.0f, 0.0f); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c); } max = 1; if(AI_SUCCESS == aiGetMaterialIntegerArray(materiau, AI_MATKEY_ENABLE_WIREFRAME, &wireframe, &max)) fill_mode = wireframe ? GL_LINE : GL_FILL; else fill_mode = GL_FILL; glPolygonMode(GL_FRONT_AND_BACK, fill_mode); max = 1; if((AI_SUCCESS == aiGetMaterialIntegerArray(materiau, AI_MATKEY_TWOSIDED, &two_sided, &max)) && two_sided) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); }