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); }
std::vector<std::shared_ptr<Material>> ModelLoader::loadMaterials(const aiScene* scene, std::map<std::string, std::shared_ptr<Texture>> textures) { std::vector<std::shared_ptr<Material>> output; for (unsigned int materialIndex = 0; materialIndex < scene->mNumMaterials; ++materialIndex) { std::shared_ptr<BasicLightingMaterial> currentGeneratedMaterial(std::make_shared<BasicLightingMaterial>()); const aiMaterial *material = scene->mMaterials[materialIndex]; aiColor4D aiDiffuse; aiColor4D aiSpecular; aiColor4D aiAmbient; aiColor4D aiEmission; glm::vec4 diffuse(1.0f, 1.0f, 1.0f, 1.0f); glm::vec4 specular(0.0f, 0.0f, 0.0f, 0.0f); glm::vec4 ambient(0.0f, 0.0f, 0.0f, 1.0f); glm::vec4 emission(0.0f, 0.0f, 0.0f, 0.0f); float shininess; float shininessStrength; unsigned int max = 1; aiString texturePath; std::shared_ptr<Texture> texture(std::make_shared<Texture>()); if (AI_SUCCESS == aiGetMaterialColor(material, AI_MATKEY_COLOR_DIFFUSE, &aiDiffuse)) { diffuse = aiColor4DToGlmVec4(aiDiffuse); } if (AI_SUCCESS == aiGetMaterialColor(material, AI_MATKEY_COLOR_SPECULAR, &aiSpecular)) { specular = aiColor4DToGlmVec4(aiSpecular); } if (AI_SUCCESS == aiGetMaterialColor(material, AI_MATKEY_COLOR_AMBIENT, &aiAmbient)) { ambient = aiColor4DToGlmVec4(aiAmbient); } if (AI_SUCCESS == aiGetMaterialColor(material, AI_MATKEY_COLOR_EMISSIVE, &aiEmission)) { emission = aiColor4DToGlmVec4(aiEmission); } aiGetMaterialFloatArray(material, AI_MATKEY_SHININESS, &shininess, &max); aiGetMaterialFloatArray(material, AI_MATKEY_SHININESS_STRENGTH, &shininessStrength, &max); shininess *= shininessStrength; if (AI_SUCCESS == material->GetTexture(aiTextureType_DIFFUSE, 0, &texturePath)) { std::string path(texturePath.data); texture = textures[path]; } currentGeneratedMaterial->setDiffuse(diffuse); currentGeneratedMaterial->setSpecular(specular); currentGeneratedMaterial->setAmbient(ambient); currentGeneratedMaterial->setEmission(emission); currentGeneratedMaterial->setShininess(shininess); currentGeneratedMaterial->setTexture(texture); output.push_back(currentGeneratedMaterial); } return output; }
MeshGL::MeshGL(aiScene* p_scene, aiMesh* p_mesh) { vao = vbo_positions = vbo_texcoords = vbo_normals = 0; aiMaterial *p_mtl = p_scene->mMaterials[p_mesh->mMaterialIndex]; aiGetMaterialColor(p_mtl, AI_MATKEY_COLOR_DIFFUSE, &material.diffuse); aiGetMaterialColor(p_mtl, AI_MATKEY_COLOR_SPECULAR, &material.specular); aiGetMaterialColor(p_mtl, AI_MATKEY_COLOR_AMBIENT, &material.ambient); aiGetMaterialColor(p_mtl, AI_MATKEY_COLOR_EMISSIVE, &material.emission); unsigned int max; aiGetMaterialFloatArray(p_mtl, AI_MATKEY_SHININESS, &material.shininess, &max); aiGetMaterialFloatArray(p_mtl, AI_MATKEY_SHININESS_STRENGTH, &material.strength, &max); glGenVertexArrays(1, &vao); glBindVertexArray(vao); if(p_mesh->HasPositions()) { nVertices = p_mesh->mNumVertices; glGenBuffers(1, &vbo_positions); glBindBuffer(GL_ARRAY_BUFFER, vbo_positions); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*3*p_mesh->mNumVertices, &p_mesh->mVertices[0], GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), BUFFER_OFFSET(0)); } if(p_mesh->HasNormals()) { glGenBuffers(1, &vbo_normals); glBindBuffer(GL_ARRAY_BUFFER, vbo_normals); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*3*p_mesh->mNumVertices, &p_mesh->mNormals[0], GL_STATIC_DRAW); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), BUFFER_OFFSET(0)); } if(p_mesh->HasFaces()) { nTriangles = p_mesh->mNumFaces; std::vector<GLuint> indices; for(GLuint i=0 ; i<p_mesh->mNumFaces ; i++) { for(GLuint j=0 ; j<p_mesh->mFaces[i].mNumIndices ; j++) { indices.push_back(p_mesh->mFaces[i].mIndices[j]); } } GLuint n = indices.size(); glGenBuffers(1, &vbo_indices); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_indices); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*3*nTriangles, indices.data(), GL_STATIC_DRAW); } }
void process_material(struct goat3d_material *mtl, struct aiMaterial *aimtl) { struct aiString aistr; struct aiColor4D color; float val; if(aiGetMaterialString(aimtl, AI_MATKEY_NAME, &aistr) == aiReturn_SUCCESS) { goat3d_set_mtl_name(mtl, aistr.data); } if(aiGetMaterialColor(aimtl, AI_MATKEY_COLOR_DIFFUSE, &color) == aiReturn_SUCCESS) { goat3d_set_mtl_attrib3f(mtl, GOAT3D_MAT_ATTR_DIFFUSE, color.r, color.g, color.b); } if(aiGetMaterialColor(aimtl, AI_MATKEY_COLOR_SPECULAR, &color) == aiReturn_SUCCESS) { float sstr = 1.0; aiGetMaterialFloatArray(aimtl, AI_MATKEY_SHININESS_STRENGTH, &sstr, 0); goat3d_set_mtl_attrib3f(mtl, GOAT3D_MAT_ATTR_SPECULAR, color.r * sstr, color.g * sstr, color.b * sstr); } if(aiGetMaterialFloatArray(aimtl, AI_MATKEY_BUMPSCALING, &val, 0) == aiReturn_SUCCESS) { goat3d_set_mtl_attrib3f(mtl, GOAT3D_MAT_ATTR_BUMP, val, val, val); } if(aiGetMaterialFloatArray(aimtl, AI_MATKEY_REFLECTIVITY, &val, 0) == aiReturn_SUCCESS) { goat3d_set_mtl_attrib1f(mtl, GOAT3D_MAT_ATTR_REFLECTION, val); } if(aiGetMaterialFloatArray(aimtl, AI_MATKEY_OPACITY, &val, 0) == aiReturn_SUCCESS) { goat3d_set_mtl_attrib1f(mtl, GOAT3D_MAT_ATTR_TRANSMISSION, 1.0 - val); } if(aiGetMaterialString(aimtl, AI_MATKEY_TEXTURE_DIFFUSE(0), &aistr) == aiReturn_SUCCESS) { goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_DIFFUSE, aistr.data); } if(aiGetMaterialString(aimtl, AI_MATKEY_TEXTURE_SPECULAR(0), &aistr) == aiReturn_SUCCESS) { goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_SPECULAR, aistr.data); } if(aiGetMaterialString(aimtl, AI_MATKEY_TEXTURE_SHININESS(0), &aistr) == aiReturn_SUCCESS) { goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_SHININESS, aistr.data); } if(aiGetMaterialString(aimtl, AI_MATKEY_TEXTURE_NORMALS(0), &aistr) == aiReturn_SUCCESS) { goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_NORMAL, aistr.data); } if(aiGetMaterialString(aimtl, AI_MATKEY_TEXTURE_REFLECTION(0), &aistr) == aiReturn_SUCCESS) { goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_REFLECTION, aistr.data); } if(aiGetMaterialString(aimtl, AI_MATKEY_TEXTURE_OPACITY(0), &aistr) == aiReturn_SUCCESS) { /* TODO this is semantically inverted... maybe add an alpha attribute? */ goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_TRANSMISSION, aistr.data); } }
void InitializeAssetMaterial( ASSET_MATERIAL* material, ASSET_MODEL* model, struct aiMaterial* material_ref, int num_indices, int index, void* application_context ) { struct aiColor4D color; aiGetMaterialColor(material_ref, AI_MATKEY_COLOR_AMBIENT, &color); material->ambient[0] = color.r; material->ambient[1] = color.g; material->ambient[2] = color.b; material->ambient[3] = 1; aiGetMaterialColor(material_ref, AI_MATKEY_COLOR_DIFFUSE, &color); material->diffuse[0] = color.r; material->diffuse[1] = color.g; material->diffuse[2] = color.b; material->diffuse[3] = 1; aiGetMaterialColor(material_ref, AI_MATKEY_COLOR_SPECULAR, &color); material->specular[0] = color.r; material->specular[1] = color.g; material->specular[2] = color.b; material->specular[3] = 1; aiGetMaterialFloatArray(material_ref, AI_MATKEY_SHININESS, &material->shininess, NULL); material->material = material_ref; material->num_indices = num_indices; material->interface_data.index = index; AssetMaterialSetTextures(material); }
bool Material::setMaterial(const aiMaterial* material){ clear(); this->uMaterial = new LightMaterial(); aiColor4D color; if (material->Get(AI_MATKEY_COLOR_AMBIENT, color) == AI_SUCCESS){ uMaterial->ambient = glm::vec4(color.r, color.g, color.b, color.a); } if (material->Get(AI_MATKEY_COLOR_DIFFUSE, color) == AI_SUCCESS){ uMaterial->diffuse = glm::vec4(color.r, color.g, color.b, color.a); } if (material->Get(AI_MATKEY_COLOR_SPECULAR, color) == AI_SUCCESS){ uMaterial->specular = glm::vec4(color.r, color.g, color.b, color.a); } if (material->Get(AI_MATKEY_COLOR_EMISSIVE, color) == AI_SUCCESS){ uMaterial->emissive = glm::vec4(color.r, color.g, color.b, color.a); } uMaterial->shininess = 0.0; unsigned int max; aiGetMaterialFloatArray(material, AI_MATKEY_SHININESS, &(uMaterial->shininess), &max); glGenBuffers(1, &uboMaterial); glBindBuffer(GL_UNIFORM_BUFFER, uboMaterial); glBufferData(GL_UNIFORM_BUFFER, sizeof(LightMaterial), (void*) uMaterial, GL_STATIC_DRAW); //glBindBufferRange(GL_UNIFORM_BUFFER, uboMaterialLoc, uboMaterial, 0, sizeof(LightMaterial)); glBindBuffer(GL_UNIFORM_BUFFER, NULL); return true; }
static int GetFloat(lua_State *L, material_t *material, const char* pKey, unsigned int type, unsigned int index) { float val; if(!material) material = checkmaterial(L, 1); if(aiGetMaterialFloatArray(material, pKey, type, index, &val, NULL) != AI_SUCCESS) return 0; lua_pushnumber(L, val); return 1; }
bool Mesh::AssimpLoader::LoadAssimpMesh(Ptr<Mesh> mesh, const aiMesh* aimesh, const aiScene* scene) { auto assetManager = AssetManager::GetInstance(); for (size_t i = 0; i < aimesh->mNumVertices; i++) { mesh->vertices.push_back(Vector3f(aimesh->mVertices[i].x, aimesh->mVertices[i].y, aimesh->mVertices[i].z)); mesh->normals.push_back(Vector3f(aimesh->mNormals[i].x, aimesh->mNormals[i].y, aimesh->mNormals[i].z)); mesh->tangents.push_back(Vector3f(aimesh->mTangents[i].x, aimesh->mTangents[i].y, aimesh->mTangents[i].z)); for (size_t j = 0; j < aimesh->GetNumUVChannels() && j < 4; j++) { mesh->uv[j].push_back(Vector2f(aimesh->mTextureCoords[j][i].x, aimesh->mTextureCoords[j][i].y)); } } for (size_t i = 0; i < aimesh->mNumFaces; i++) { for (size_t j = 0; j < aimesh->mFaces[i].mNumIndices; j++) mesh->triangles.push_back(aimesh->mFaces[i].mIndices[j]); } // TODO : 支持更多材质样式 if (aimesh->mMaterialIndex >= 0) { aiMaterial* material = scene->mMaterials[aimesh->mMaterialIndex]; aiColor4D diffuse, specular, ambient, emissive; ai_real shininess; unsigned int max = 1; if (AI_SUCCESS == aiGetMaterialColor(material, AI_MATKEY_COLOR_DIFFUSE, &diffuse)) mesh->material.diffuse = Vector4f(diffuse.r, diffuse.g, diffuse.b, diffuse.a); if (AI_SUCCESS == aiGetMaterialColor(material, AI_MATKEY_COLOR_SPECULAR, &specular)) mesh->material.specular = Vector4f(specular.r, specular.g, specular.b, specular.a); if (AI_SUCCESS == aiGetMaterialColor(material, AI_MATKEY_COLOR_AMBIENT, &ambient)) mesh->material.ambient = Vector4f(ambient.r, ambient.g, ambient.b, ambient.a); if (AI_SUCCESS == aiGetMaterialColor(material, AI_MATKEY_COLOR_EMISSIVE, &emissive)) mesh->material.emissive = Vector4f(emissive.r, emissive.g, emissive.b, emissive.a); if (AI_SUCCESS == aiGetMaterialFloatArray(material, AI_MATKEY_SHININESS, &shininess, &max)) mesh->material.shininess = shininess; for (size_t i = 0; i < material->GetTextureCount(aiTextureType_DIFFUSE); i++) { aiString path; material->GetTexture(aiTextureType_DIFFUSE, i, &path); String fullPath = this->dir + "/" + path.data; Ptr<Texture> tex = assetManager->CreateTextureFromFile(fullPath); if (tex == nullptr) return false; mesh->material.texture = tex; break; // 目前只支持一张diffuse texture } } return true; }
void Model::applyMateriale(const aiMaterial* materiale, Materiale& meshMat) { std::cout << "Applying mesh material" << std::endl; aiString texPath; if(AI_SUCCESS == materiale->GetTexture(aiTextureType_DIFFUSE, 0, &texPath)){ std::string fullPath = folderPath + texPath.C_Str(); // Check if this texture was already loaded. std::map<std::string, unsigned int>::iterator it = textureID_map.find(fullPath); if(it == textureID_map.end()){ Image img; loadImage(img, fullPath.c_str()); meshMat.textureID = loadTexture(img); }else{ meshMat.textureID = it->second; } std::cout << "loaded texture: " << meshMat.textureID << std::endl; }else{ Image img; // generate white dummy 16x16 texture so we don't have to // switch shaders for untextured meshes img.components = 3; img.height = 1; img.width = 1; img.data.resize(1 * 1 * 3); for(int i = 0; i < 1 * 1 * 3; i++){ img.data[i] = (unsigned char) 255; } meshMat.textureID = loadTexture(img); std::cout << "Created a dummy texture: " << meshMat.textureID << std::endl; } // Fetch material specs aiColor4D diffuse; if(AI_SUCCESS == aiGetMaterialColor(materiale, AI_MATKEY_COLOR_DIFFUSE, &diffuse)){ meshMat.diffuse = glm::vec3(diffuse.r, diffuse.g, diffuse.b); } aiColor4D ambient; if(AI_SUCCESS == aiGetMaterialColor(materiale, AI_MATKEY_COLOR_AMBIENT, &ambient)){ meshMat.ambient = glm::vec3(ambient.r, ambient.g, ambient.b); } aiColor4D specular; if(AI_SUCCESS == aiGetMaterialColor(materiale, AI_MATKEY_COLOR_SPECULAR, &specular)){ meshMat.specular = glm::vec3(specular.r, specular.g, specular.b); } float shininess = 0.0f; unsigned int max; aiGetMaterialFloatArray(materiale, AI_MATKEY_SHININESS, &shininess, &max); meshMat.shininess = shininess; }
static int Texture_axis(lua_State *L) { vector3_t vec; material_t *material = checkmaterial(L, 1); unsigned int type = checktexturetype(L, 2); unsigned int index = checkindex(L, 3); unsigned int max = sizeof(vector3_t); if(AI_SUCCESS != aiGetMaterialFloatArray(material, _AI_MATKEY_TEXMAP_AXIS_BASE, type, index, (float*)&vec, &max) || sizeof(vector3_t) != max) return 0; return pushvector3(L, &vec, 0); }
static int Texture_uvscaling(lua_State *L) { struct aiUVTransform trafo; material_t *material = checkmaterial(L, 1); unsigned int type = checktexturetype(L, 2); unsigned int index = checkindex(L, 3); unsigned int max = sizeof(struct aiUVTransform); if(AI_SUCCESS != aiGetMaterialFloatArray(material, _AI_MATKEY_UVTRANSFORM_BASE, type, index, (float*)&trafo, &max) || sizeof(struct aiUVTransform) != max) return 0; return pushvector2(L, &(trafo.mScaling), 0); }
static int Texture_uvrotation(lua_State *L) { struct aiUVTransform trafo; material_t *material = checkmaterial(L, 1); unsigned int type = checktexturetype(L, 2); unsigned int index = checkindex(L, 3); unsigned int max = sizeof(struct aiUVTransform); if(AI_SUCCESS != aiGetMaterialFloatArray(material, _AI_MATKEY_UVTRANSFORM_BASE, type, index, (float*)&trafo, &max) || sizeof(struct aiUVTransform) != max) return 0; lua_pushnumber(L, trafo.mRotation); 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 AssimpScene::setupVAOs( OpenGLFunctions & gl , const aiScene * scene) { assert(scene); // For each mesh for (unsigned int m = 0; m < scene->mNumMeshes; ++m) { const aiMesh * mesh = scene->mMeshes[m]; // create array with faces // have to convert from Assimp format to array std::vector<unsigned int> indices(mesh->mNumFaces * 3); for (unsigned int f = 0, i = 0; f < mesh->mNumFaces; ++f, i += 3) { const aiFace * face = &mesh->mFaces[f]; indices[i + 0] = face->mIndices[0]; indices[i + 1] = face->mIndices[1]; indices[i + 2] = face->mIndices[2]; } AssimpMesh * amesh = new AssimpMesh(); amesh->faces = mesh->mNumFaces; amesh->vao.create(); amesh->vao.bind(); // create buffers amesh->indices = new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer); amesh->indices->create(); amesh->indices->setUsagePattern(QOpenGLBuffer::StaticDraw); amesh->indices->bind(); amesh->indices->allocate(indices.data(), indices.size() * sizeof(unsigned int)); if (mesh->HasPositions()) { amesh->vertices = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); amesh->vertices->create(); amesh->vertices->setUsagePattern(QOpenGLBuffer::StaticDraw); amesh->vertices->bind(); amesh->vertices->allocate(mesh->mVertices, mesh->mNumVertices * sizeof(float) * 3); gl.glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, nullptr); gl.glEnableVertexAttribArray(0); } if (mesh->HasNormals()) { amesh->normals = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); amesh->normals->create(); amesh->normals->setUsagePattern(QOpenGLBuffer::StaticDraw); amesh->normals->bind(); amesh->normals->allocate(mesh->mNormals, mesh->mNumVertices * sizeof(float) * 3); gl.glVertexAttribPointer(1, 3, GL_FLOAT, GL_TRUE, sizeof(float) * 3, nullptr); gl.glEnableVertexAttribArray(1); } if (mesh->HasTextureCoords(0)) { float * texcs = new float[2 * mesh->mNumVertices]; for (unsigned int t = 0; t < mesh->mNumVertices; ++t) { texcs[t * 2 + 0] = mesh->mTextureCoords[0][t].x; texcs[t * 2 + 1] = mesh->mTextureCoords[0][t].y; } amesh->texcs= new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); amesh->texcs->create(); amesh->texcs->setUsagePattern(QOpenGLBuffer::StaticDraw); amesh->texcs->bind(); amesh->texcs->allocate(texcs, mesh->mNumVertices * sizeof(float) * 2); gl.glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, nullptr); gl.glEnableVertexAttribArray(2); } amesh->vao.release(); AssimpMaterial & material(amesh->material); // create material uniform buffer aiMaterial * mtl = scene->mMaterials[mesh->mMaterialIndex]; // support single texture on diffuse channel only for now... TODO aiString path; if (AI_SUCCESS == mtl->GetTexture(aiTextureType_DIFFUSE, 0, &path)) { material.texture = FileAssociatedTexture::getOrCreate2D(QString(path.C_Str()), gl); material.texCount = 1; } else material.texCount = 0; retrieveColor(mtl, AI_MATKEY_COLOR_DIFFUSE, material.diffuse, 0.8f, 0.8f, 0.8f, 1.0f); retrieveColor(mtl, AI_MATKEY_COLOR_AMBIENT, material.ambient, 0.2f, 0.2f, 0.2f, 1.0f); retrieveColor(mtl, AI_MATKEY_COLOR_SPECULAR, material.specular, 0.0f, 0.0f, 0.0f, 1.0f); retrieveColor(mtl, AI_MATKEY_COLOR_EMISSIVE, material.emissive, 0.0f, 0.0f, 0.0f, 1.0f); material.shininess = 0.f; unsigned int max; aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS, &material.shininess, &max); m_meshes.push_back(amesh); } }
void RenderObject::pre_render() { recursive_pre_render(scene->mRootNode); //Init materials: for(unsigned int i= 0; i < scene->mNumMaterials; ++i) { const aiMaterial * mtl = scene->mMaterials[i]; Material mtl_data; aiString path; if(mtl->GetTextureCount(aiTextureType_DIFFUSE) > 0 && mtl->GetTexture(aiTextureType_DIFFUSE, 0, &path, NULL, NULL, NULL, NULL, NULL) == AI_SUCCESS) { std::string p(path.data); mtl_data.texture = load_texture(p); } else if(mtl->GetTextureCount(aiTextureType_AMBIENT) > 0 && mtl->GetTexture(aiTextureType_AMBIENT, 0, &path, NULL, NULL, NULL, NULL, NULL) == AI_SUCCESS) { std::string p(path.data); mtl_data.texture = load_texture(p); } if ( !mtl_data.texture ){ fprintf(stderr, "RenderObject `%s' texture failed to load.\n", name.c_str()); util_abort(); } //Check for normalmap: if(mtl->GetTextureCount(aiTextureType_HEIGHT) > 0 && mtl->GetTexture(aiTextureType_HEIGHT, 0, &path, NULL, NULL, NULL, NULL, NULL) == AI_SUCCESS) { const std::string p(path.data); mtl_data.normal_map = load_texture(p); } if(mtl->GetTextureCount(aiTextureType_SHININESS) > 0 && mtl->GetTexture(aiTextureType_SHININESS, 0, &path, NULL, NULL, NULL, NULL, NULL) == AI_SUCCESS) { const std::string p(path.data); mtl_data.specular_map = load_texture(p); } if(mtl->GetTextureCount(aiTextureType_OPACITY) > 0 && mtl->GetTexture(aiTextureType_OPACITY, 0, &path, NULL, NULL, NULL, NULL, NULL) == AI_SUCCESS) { const std::string p(path.data); mtl_data.alpha_map = load_texture(p); } aiString name; if(AI_SUCCESS == mtl->Get(AI_MATKEY_NAME, name)) fprintf(verbose, "Loaded material %d %s\n", i, name.data); aiColor4D value; if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &value)) color4_to_vec4(&value, mtl_data.diffuse); if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &value)) color4_to_vec4(&value, mtl_data.specular); if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &value)) color4_to_vec4(&value, mtl_data.ambient); if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &value)) color4_to_vec4(&value, mtl_data.emission); unsigned int max = 1; float strength; int ret1 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS, &mtl_data.shininess, &max); if(ret1 == AI_SUCCESS) { max = 1; int ret2 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS_STRENGTH, &strength, &max); if(ret2 == AI_SUCCESS) mtl_data.shininess *= strength; } else { mtl_data.shininess = 0.0f; } if ( mtl_data.shininess < 0.001f ){ /* arbitrary small value */ mtl_data.shininess = 0.001f; /* in glsl pow(x,0) is undefined */ mtl_data.specular = glm::vec4(0.f, 0.f, 0.f, 0.f); } max = 1; materials.push_back(mtl_data); } }
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); }
void AssimpLoader::GetMaterialPropreties(RenderableObject* assimpMesh, const struct aiMaterial *mtl) { Color color; // Manage the diffuse color struct aiColor4D diffuseColor; if (AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuseColor)) { color = Color(diffuseColor.r, diffuseColor.g, diffuseColor.b, diffuseColor.a); assimpMesh->AddMaterial(DIFFUSE_MATERIAL, color); } else { color = Color(1, 1, 1, 1); assimpMesh->AddMaterial(DIFFUSE_MATERIAL, color); } // Manage the specular color struct aiColor4D specularColor; if (AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &specularColor)) { color = Color(specularColor.r, specularColor.g, specularColor.b, 0); // Try to extract Specular shininess 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) { color.A = strength * shininess; } assimpMesh->AddMaterial(SPECULAR_MATERIAL, color); } else { color = Color(1, 1, 1, 0); assimpMesh->AddMaterial(SPECULAR_MATERIAL, color); } // Manage the Ambiant color struct aiColor4D ambiantColor; if (AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &ambiantColor)) { color = Color(ambiantColor.r, ambiantColor.g, ambiantColor.b, ambiantColor.a); assimpMesh->AddMaterial(AMBIANT_MATERIAL, color); } else { color = Color(1, 1, 1, 1); assimpMesh->AddMaterial(AMBIANT_MATERIAL, color); } // Manage emission color struct aiColor4D emissionColor; if (AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &emissionColor)) { color = Color(emissionColor.r, emissionColor.g, emissionColor.b, emissionColor.a); assimpMesh->AddMaterial(EMISSION_MATERIAL, color); } else { color = Color(1, 1, 1, 1); assimpMesh->AddMaterial(EMISSION_MATERIAL, color); } }
void Model::genVAOsAndUniformBuffer(const aiScene *sc) { checkForErrors(); struct MyMesh aMesh; struct MyMaterial aMat; GLuint buffer; // For each mesh for (unsigned int n = 0; n < sc->mNumMeshes; ++n) { const aiMesh* mesh = sc->mMeshes[n]; // create array with faces // have to convert from Assimp format to array unsigned int *faceArray; faceArray = (unsigned int *)malloc(sizeof(unsigned int) * mesh->mNumFaces * 3); unsigned int faceIndex = 0; for (unsigned int t = 0; t < mesh->mNumFaces; ++t) { const aiFace* face = &mesh->mFaces[t]; memcpy(&faceArray[faceIndex], face->mIndices,3 * sizeof(unsigned int)); faceIndex += 3; } aMesh.numFaces = sc->mMeshes[n]->mNumFaces; // generate Vertex Array for mesh glGenVertexArrays(1,&(aMesh.vao)); glBindVertexArray(aMesh.vao); // buffer for faces glGenBuffers(1, &buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * mesh->mNumFaces * 3, faceArray, GL_STATIC_DRAW); free(faceArray); // buffer for vertex positions if (mesh->HasPositions()) { glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*mesh->mNumVertices, mesh->mVertices, GL_STATIC_DRAW); glEnableVertexAttribArray(vertexLoc); glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, 0, 0, 0); } // buffer for vertex normals if (mesh->HasNormals()) { glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*mesh->mNumVertices, mesh->mNormals, GL_STATIC_DRAW); glEnableVertexAttribArray(normalLoc); glVertexAttribPointer(normalLoc, 3, GL_FLOAT, 0, 0, 0); } // buffer for vertex texture coordinates if (mesh->HasTextureCoords(0)) { float *texCoords = (float *)malloc(sizeof(float)*2*mesh->mNumVertices); for (unsigned int k = 0; k < mesh->mNumVertices; ++k) { texCoords[k*2] = mesh->mTextureCoords[0][k].x; texCoords[k*2+1] = mesh->mTextureCoords[0][k].y; } glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*mesh->mNumVertices, texCoords, GL_STATIC_DRAW); glEnableVertexAttribArray(texCoordLoc); glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, 0, 0, 0); } // unbind buffers glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER,0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); // create material uniform buffer aiMaterial *mtl = sc->mMaterials[mesh->mMaterialIndex]; aiString texPath; //contains filename of texture if(AI_SUCCESS == mtl->GetTexture(aiTextureType_DIFFUSE, 0, &texPath)){ //bind texture unsigned int texId = textureIdMap[texPath.data]; aMesh.texIndex = texId; aMat.texCount = 1; } else aMat.texCount = 0; float c[4]; set_float4(c, 0.8f, 0.8f, 0.8f, 1.0f); aiColor4D diffuse; if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse)) color4_to_float4(&diffuse, c); memcpy(aMat.diffuse, c, sizeof(c)); set_float4(c, 0.2f, 0.2f, 0.2f, 1.0f); aiColor4D ambient; if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &ambient)) color4_to_float4(&ambient, c); memcpy(aMat.ambient, c, sizeof(c)); set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f); aiColor4D specular; if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &specular)) color4_to_float4(&specular, c); memcpy(aMat.specular, c, sizeof(c)); set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f); aiColor4D emission; if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &emission)) color4_to_float4(&emission, c); memcpy(aMat.emissive, c, sizeof(c)); float shininess = 0.0; unsigned int max; aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS, &shininess, &max); aMat.shininess = shininess; glGenBuffers(1,&(aMesh.uniformBlockIndex)); glBindBuffer(GL_UNIFORM_BUFFER,aMesh.uniformBlockIndex); glBufferData(GL_UNIFORM_BUFFER, sizeof(aMat), (void *)(&aMat), GL_STATIC_DRAW); myMeshes.push_back(aMesh); } }
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 VSResModelLib::genVAOsAndUniformBuffer(const struct aiScene *sc) { struct MyMesh aMesh; struct Material aMat; GLuint buffer; int totalTris = 0; unsigned int *adjFaceArray; VSLOG(mLogInfo, "Number of Meshes: %d",sc->mNumMeshes); // For each mesh for (unsigned int n = 0; n < sc->mNumMeshes; ++n) { const struct aiMesh* mesh = sc->mMeshes[n]; if (mesh->mPrimitiveTypes != 4) { aMesh.numIndices = 0; pMyMeshesAux.push_back(aMesh); continue; } VSLOG(mLogInfo, "Mesh[%d] Triangles %d",n, mesh->mNumFaces); totalTris += mesh->mNumFaces; // create array with faces // have to convert from Assimp format to array unsigned int *faceArray; faceArray = (unsigned int *)malloc( sizeof(unsigned int) * mesh->mNumFaces * 3); unsigned int faceIndex = 0; for (unsigned int t = 0; t < mesh->mNumFaces; ++t) { const struct aiFace* face = &mesh->mFaces[t]; memcpy(&faceArray[faceIndex], face->mIndices, 3 * sizeof(unsigned int)); faceIndex += 3; } if (pUseAdjacency) { // Create the half edge structure std::map<std::pair<unsigned int,unsigned int>, struct HalfEdge *> myEdges; struct HalfEdge *edge; // fill it up with edges. twin info will be added latter edge = (struct HalfEdge *)malloc(sizeof(struct HalfEdge) * mesh->mNumFaces * 3); for (unsigned int i = 0; i < mesh->mNumFaces; ++i) { edge[i*3].vertex = faceArray[i*3+1]; edge[i*3+1].vertex = faceArray[i*3+2]; edge[i*3+2].vertex = faceArray[i*3]; edge[i*3].next = &edge[i*3+1]; edge[i*3+1].next = &edge[i*3+2]; edge[i*3+2].next = &edge[i*3]; myEdges[std::pair<unsigned int,unsigned int>(faceArray[i*3+2],faceArray[i*3])] = &edge[i*3]; myEdges[std::pair<unsigned int,unsigned int>(faceArray[i*3],faceArray[i*3+1])] = &edge[i*3+1]; myEdges[std::pair<unsigned int,unsigned int>(faceArray[i*3+1],faceArray[i*3+2])] = &edge[i*3+2]; } // add twin info std::map<std::pair<unsigned int,unsigned int>, struct HalfEdge *>::iterator iter; std::pair<unsigned int,unsigned int> edgeIndex, twinIndex; iter = myEdges.begin(); for (; iter != myEdges.end(); ++iter) { edgeIndex = iter->first; twinIndex = std::pair<unsigned int, unsigned int>(edgeIndex.second, edgeIndex.first); if (myEdges.count(twinIndex)) iter->second->twin = myEdges[twinIndex]; else iter->second->twin = NULL; } adjFaceArray = (unsigned int *)malloc(sizeof(unsigned int) * mesh->mNumFaces * 6); for (unsigned int i = 0; i < mesh->mNumFaces; i++) { // NOTE: twin may be null adjFaceArray[i*6] = edge[3*i + 0].next->vertex; adjFaceArray[i*6+1] = edge[3*i + 0].twin?edge[3*i + 0].twin->vertex:edge[3*i + 0].next->vertex; adjFaceArray[i*6+2] = edge[3*i + 1].next->vertex; adjFaceArray[i*6+3] = edge[3*i + 1].twin?edge[3*i + 1].twin->vertex:edge[3*i + 1].next->vertex; adjFaceArray[i*6+4] = edge[3*i + 2].next->vertex; adjFaceArray[i*6+5] = edge[3*i + 2].twin?edge[3*i + 2].twin->vertex:edge[3*i + 2].next->vertex; } } //printf("\n"); //for (int i = 0; i < mesh->mNumFaces * 3; ++i) // printf("%d ", faceArray[i]); //printf("\n"); //for (int i = 0; i < mesh->mNumFaces * 6; ++i) // printf("%d ", adjFaceArray[i]); //printf("\n"); aMesh.numIndices = sc->mMeshes[n]->mNumFaces * 3; // generate Vertex Array for mesh glGenVertexArrays(1,&(aMesh.vao)); glBindVertexArray(aMesh.vao); // buffer for faces glGenBuffers(1, &buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer); if (pUseAdjacency) { glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * mesh->mNumFaces * 6, adjFaceArray, GL_STATIC_DRAW); free(adjFaceArray); } else glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * mesh->mNumFaces * 3, faceArray, GL_STATIC_DRAW); free(faceArray); // buffer for vertex positions if (mesh->HasPositions()) { glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*mesh->mNumVertices, mesh->mVertices, GL_STATIC_DRAW); glEnableVertexAttribArray( VSShaderLib::VERTEX_COORD_ATTRIB); glVertexAttribPointer(VSShaderLib::VERTEX_COORD_ATTRIB, 3, GL_FLOAT, 0, 0, 0); } // buffer for vertex normals if (mesh->HasNormals()) { glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*mesh->mNumVertices, mesh->mNormals, GL_STATIC_DRAW); glEnableVertexAttribArray(VSShaderLib::NORMAL_ATTRIB); glVertexAttribPointer(VSShaderLib::NORMAL_ATTRIB, 3, GL_FLOAT, 0, 0, 0); } // buffer for vertex normals if (mesh->HasTangentsAndBitangents()) { glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*mesh->mNumVertices, mesh->mTangents, GL_STATIC_DRAW); glEnableVertexAttribArray(VSShaderLib::TANGENT_ATTRIB); glVertexAttribPointer(VSShaderLib::TANGENT_ATTRIB, 3, GL_FLOAT, 0, 0, 0); } // buffer for vertex normals if (mesh->HasTangentsAndBitangents()) { glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*mesh->mNumVertices, mesh->mBitangents, GL_STATIC_DRAW); glEnableVertexAttribArray(VSShaderLib::BITANGENT_ATTRIB); glVertexAttribPointer(VSShaderLib::BITANGENT_ATTRIB, 3, GL_FLOAT, 0, 0, 0); } // buffer for vertex texture coordinates if (mesh->HasTextureCoords(0)) { float *texCoords = (float *)malloc( sizeof(float)*2*mesh->mNumVertices); for (unsigned int k = 0; k < mesh->mNumVertices; ++k) { texCoords[k*2] = mesh->mTextureCoords[0][k].x; texCoords[k*2+1] = mesh->mTextureCoords[0][k].y; } glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*mesh->mNumVertices, texCoords, GL_STATIC_DRAW); glEnableVertexAttribArray( VSShaderLib::TEXTURE_COORD_ATTRIB); glVertexAttribPointer( VSShaderLib::TEXTURE_COORD_ATTRIB, 2, GL_FLOAT, 0, 0, 0); free(texCoords); } // unbind buffers glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER,0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); // create material uniform buffer struct aiMaterial *mtl = sc->mMaterials[mesh->mMaterialIndex]; aiString texPath; //contains filename of texture for (int j = 0; j < VSResourceLib::MAX_TEXTURES; ++j) aMesh.texUnits[j] = 0; if(AI_SUCCESS == mtl->GetTexture(aiTextureType_DIFFUSE, 0, &texPath)) { //bind texture aMesh.texUnits[0] = pTextureIdMap[texPath.data]; aMesh.texTypes[0] = GL_TEXTURE_2D; aMat.texCount = 1; } else { aMesh.texUnits[0] = 0; aMat.texCount = 0; } float c[4]; set_float4(c, 0.8f, 0.8f, 0.8f, 1.0f); aiColor4D diffuse; if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse)) color4_to_float4(&diffuse, c); memcpy(aMat.diffuse, c, sizeof(c)); set_float4(c, 0.2f, 0.2f, 0.2f, 1.0f); aiColor4D ambient; if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &ambient)) color4_to_float4(&ambient, c); memcpy(aMat.ambient, c, sizeof(c)); set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f); aiColor4D specular; if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &specular)) color4_to_float4(&specular, c); memcpy(aMat.specular, c, sizeof(c)); set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f); aiColor4D emission; if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &emission)) color4_to_float4(&emission, c); memcpy(aMat.emissive, c, sizeof(c)); float shininess = 0.0; unsigned int max; aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS, &shininess, &max); aMat.shininess = shininess; aMesh.mat = aMat; pMyMeshesAux.push_back(aMesh); } mVSML->loadIdentity(VSMathLib::AUX0); recursive_walk_for_matrices(sc, sc->mRootNode); pMyMeshesAux.clear(); VSLOG(mLogInfo, "Total Meshes: %d | Faces: %d", sc->mNumMeshes, totalTris); }
//////////////////////////////////////////////////////////////////////// /// /// @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); }
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 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); } }