void Model::processMaterial(const aiScene* scene) { aiColor4D ka, kd, ks; GLuint texDiffuse, texNormal, texSpecular; aiString str; for(GLuint i = 0; i < scene->mNumMaterials; i++) { if(AI_SUCCESS == scene->mMaterials[i]->GetTexture(aiTextureType_DIFFUSE, 0, &str)) texDiffuse = TextureFromFile(str.C_Str(), this->directory); else texDiffuse = 0; if(AI_SUCCESS == scene->mMaterials[i]->GetTexture(aiTextureType_HEIGHT, 0, &str)) texNormal = TextureFromFile(str.C_Str(), this->directory); else texNormal = 0; if(AI_SUCCESS == scene->mMaterials[i]->GetTexture(aiTextureType_SPECULAR, 0, &str)) texSpecular = TextureFromFile(str.C_Str(), this->directory); else texSpecular = 0; aiGetMaterialColor(scene->mMaterials[i], AI_MATKEY_COLOR_AMBIENT, &ka); aiGetMaterialColor(scene->mMaterials[i], AI_MATKEY_COLOR_DIFFUSE, &kd); aiGetMaterialColor(scene->mMaterials[i], AI_MATKEY_COLOR_SPECULAR, &ks); m_material.push_back(Material(ka, kd, ks, texDiffuse, texNormal, texSpecular)); } }
vector<Texture> Model::loadMaterialTextures(aiMaterial* mat, aiTextureType type, string typeName) { vector<Texture> textures; for(GLuint i = 0; i < mat->GetTextureCount(type); i++) { aiString str; mat->GetTexture(type, i, &str); // Check if texture was loaded before and if so, continue to next iteration: skip loading a new texture GLboolean skip = false; for(GLuint j = 0; j < textures_loaded.size(); j++) { if(textures_loaded[j].path == str) { textures.push_back(textures_loaded[j]); skip = true; // A texture with the same file path has already been loaded, continue to next one. (optimization) break; } } if(!skip) { // If texture hasn't been loaded already, load it ! Texture texture; texture.id = TextureFromFile(str.C_Str(), this->directory); texture.type = typeName; texture.path = str; textures.push_back(texture); this->textures_loaded.push_back(texture); // Store it as texture loaded for entire model, to ensure we won't unnecesery load duplicate textures. } } return textures; }
vector<Texture> Model::loadMaterialTextures(aiMaterial* mat, aiTextureType type, string typeName) { vector<Texture> textures; for (GLuint i = 0; i < mat->GetTextureCount(type); i++) { aiString str; mat->GetTexture(type, i, &str); GLboolean skip = false; for (GLuint j = 0; j < textures_loaded.size(); j++) { if (textures_loaded[j].path == str) { textures.push_back(textures_loaded[j]); skip = true; break; } } if (!skip) { Texture texture; texture.id = TextureFromFile(str.C_Str(), this->directory); texture.type = typeName; texture.path = str; textures.push_back(texture); this->textures_loaded.push_back(texture); } } return textures; }
vector<Texture> Model::loadMaterialTextures(aiMaterial* mat, aiTextureType type, string typeName) { vector<Texture> textures; for (GLuint i = 0; i < mat->GetTextureCount(type); i++) { aiString str; mat->GetTexture(type, i, &str); //Check if texture was loaded before and if so, continue to next iteration: skip loading a new texture GLboolean skip = false; for (GLuint j = 0; j < textures_loaded.size(); j++) { if (textures_loaded[j].path == str) { textures.push_back(textures_loaded[j]); skip = true; break; } } if (!skip) { //If texture hasn't been loaded already, load it Texture texture; texture.id = TextureFromFile(str.C_Str(), this->directory); texture.type = typeName; texture.path = str; textures.push_back(texture); this->textures_loaded.push_back(texture); } } return textures; }
std::vector<Texture> Model::loadMaterialTextures(aiMaterial *mat, aiTextureType type, std::string typeName) { std::vector<Texture> textures; for(GLuint i = 0; i < mat->GetTextureCount(type); i++) { aiString str; mat->GetTexture(type, i, &str); Texture texture; texture.id = TextureFromFile(str.C_Str(), directory); texture.type = typeName; texture.path = str.C_Str(); textures.push_back(texture); } return textures; }
shared_ptr<Texture> TexturesManager::CreateTexture2D(string path, string directory, TextureType type, float blend, TextureBlendOperation op) { auto it = find_if(texturesBuffers.begin(), texturesBuffers.end(), [&path](const shared_ptr<Texture>& obj) {return obj->path == path; }); if (it != texturesBuffers.end()) { auto index = std::distance(texturesBuffers.begin(), it); return texturesBuffers[index]; } //It's a new texture int width = 0, height = 0; string filename = directory + '/' + string(path); unique_ptr<unsigned char> tempImage = TextureFromFile(filename, width, height); shared_ptr<Texture> texturePtr = make_shared<Texture2D>(width, height, type, path, &*tempImage, blend, op); texturesBuffers.push_back(texturePtr); return texturePtr; }
// Checks all material textures of a given type and loads the textures if they're not loaded yet. // The required info is returned as a Texture struct. vector<Texture> * Model::loadMaterialTextures(const aiMaterial* mat, aiTextureType type) { vector<Texture> allTextures; vector<Texture> * textures = new vector<Texture>(); for(GLuint i = 0; i < mat->GetTextureCount(type); i++) { aiString str; mat->GetTexture(type, i, &str); // Check if texture was loaded before and if so, continue to next iteration: skip loading a new texture GLboolean skip = false; for(GLuint j = 0; j < allTextures.size(); j++) { if(allTextures.at(j).path == str) { textures->push_back(allTextures.at(j)); skip = true; // A texture with the same filepath has already been loaded, continue to next one. (optimization) break; } } if(!skip) { // If texture hasn't been loaded already, load it Texture texture(TextureFromFile(str.C_Str(), directory == "" ? NULL : directory.c_str()), str); textures->push_back(texture); // Store it as texture loaded for entire model, to ensure we won't unnecesery load duplicate textures. allTextures.push_back(texture); } } return textures; }
void CMyOGLApp::Init() { // clear color set to blue-ish glClearColor(0.125f, 0.25f, 0.5f, 1.0f); glEnable(GL_CULL_FACE); // turn on back-face culling glEnable(GL_DEPTH_TEST); // enable depth-test // // define the geometry // Vertex vert[] = { // x, y, z nx,ny,nz s, t {glm::vec3(-10, 0, -10), glm::vec3(0, 1, 0), glm::vec2(0, 0)}, {glm::vec3( 10, 0, -10), glm::vec3(0, 1, 0), glm::vec2(1, 0)}, {glm::vec3(-10, 0, 10), glm::vec3(0, 1, 0), glm::vec2(0, 1)}, {glm::vec3( 10, 0, 10), glm::vec3(0, 1, 0), glm::vec2(1, 1)}, }; // create index buffer GLushort indices[]= { 1,0,2, 1,2,3, }; // create a VAO glGenVertexArrays(1, &m_vaoID); // activate the new VAO m_vaoID glBindVertexArray(m_vaoID); // create a VBO glGenBuffers(1, &m_vboID); glBindBuffer(GL_ARRAY_BUFFER, m_vboID); // activate the VBO m_vboID // load the data stored in array vert into the VBO (essentially: upload the data to the GPU) glBufferData( GL_ARRAY_BUFFER, // allocate memory for the active VBO and set its data sizeof(vert), // size of the VBO allocation, in bytes vert, // load data into the VBO from this location of the system memory GL_STATIC_DRAW); // we only want to store data into the VBO once (STATIC), and we want to use the VBO as a source for drawing our scene at each frame (DRAW) // for other usage flags see http://www.opengl.org/sdk/docs/man/xhtml/glBufferData.xml // {STREAM, STATIC, DYNAMIC} and {DRAW, READ, COPY} // activate the first general attribute 'channel' in the VAO glEnableVertexAttribArray(0); glVertexAttribPointer( 0, // set the attributes of VAO channel 0 3, // this channel has 3 componenets GL_FLOAT, // each of those componenets are floats GL_FALSE, // do not normalize sizeof(Vertex), // stride 0 // channel 0`s data begins at the beginning of the VBO, no offset ); // activate 'channel' idx 1 glEnableVertexAttribArray(1); glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(glm::vec3)) ); // texture coordinates glEnableVertexAttribArray(2); glVertexAttribPointer( 2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(2*sizeof(glm::vec3)) ); // create index buffer glGenBuffers(1, &m_ibID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibID); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // // shader initialization // GLuint vs_ID = loadShader(GL_VERTEX_SHADER, "myVert.vert"); GLuint fs_ID = loadShader(GL_FRAGMENT_SHADER, "myFrag.frag"); // create the shader container (program) m_programID = glCreateProgram(); // attach the vertex and fragment (pixel) shaders to the program glAttachShader(m_programID, vs_ID); glAttachShader(m_programID, fs_ID); // make correspondances between the VAO channels and the shader 'in' variables // IMPORTANT: do this prior to linking the programs! glBindAttribLocation( m_programID, // ID of the shader program from which we want to map a variable to a channel 0, // the VAO channel number we want to bind the variable to "vs_in_pos"); // the name of the variable in the shader glBindAttribLocation( m_programID, 1, "vs_in_normal"); glBindAttribLocation( m_programID, 2, "vs_in_tex0"); // link the shaders glLinkProgram(m_programID); // check the linking GLint infoLogLength = 0, result = 0; glGetProgramiv(m_programID, GL_LINK_STATUS, &result); glGetProgramiv(m_programID, GL_INFO_LOG_LENGTH, &infoLogLength); if ( GL_FALSE == result ) { std::vector<char> ProgramErrorMessage( infoLogLength ); glGetProgramInfoLog(m_programID, infoLogLength, NULL, &ProgramErrorMessage[0]); fprintf(stdout, "%s\n", &ProgramErrorMessage[0]); char* aSzoveg = new char[ProgramErrorMessage.size()]; memcpy( aSzoveg, &ProgramErrorMessage[0], ProgramErrorMessage.size()); MessageBoxA(0, aSzoveg, "Sáder Huba panasza", 0); delete aSzoveg; } // we can dispose of the vertex and fragment shaders glDeleteShader( vs_ID ); glDeleteShader( fs_ID ); // // other initializations // // set the projection matrix m_matProj = glm::perspective( 45.0f, m_client_width/(float)m_client_height, 1.0f, 1000.0f ); // query the IDs of the shader uniform variables m_loc_world = glGetUniformLocation( m_programID, "world"); m_loc_worldIT = glGetUniformLocation( m_programID, "worldIT"); m_loc_view = glGetUniformLocation( m_programID, "view" ); m_loc_proj = glGetUniformLocation( m_programID, "proj" ); m_loc_texture = glGetUniformLocation( m_programID, "texture" ); // generate the texture m_textureID = TextureFromFile("texture.jpg"); }