void SimpleSceneGraph::Render(SimpleProgram &program) { SimpleUniform InverseCameraMatrix; SimpleUniform CameraMatrix; SimpleUniform ProjectionXMatrix; SimpleUniform ProjectionYMatrix; camera.projectionMatrix.LoadIdentity(); camera.projectionMatrix.Perspective(camera.fov, camera.imageAspect, camera.imageNearZ, camera.imageFarZ); ProjectionXMatrix = camera.projectionMatrix; camera.projectionMatrix.LoadIdentity(); camera.projectionMatrix.PerspectiveY(camera.fov, camera.imageAspect, camera.imageNearZ, camera.imageFarZ); ProjectionYMatrix = camera.projectionMatrix; CameraMatrix = camera.viewMatrix; InverseCameraMatrix = camera.viewMatrix.AsInverse(); program.Use(); program.ApplyUniform("NewProjectionXMatrix", ProjectionXMatrix); program.ApplyUniform("NewProjectionYMatrix", ProjectionYMatrix); program.ApplyUniform("NewInverseCameraMatrix", InverseCameraMatrix); program.ApplyUniform("NewCameraMatrix", CameraMatrix); if (debugging) hflog.info("%s(): Starting Render", __FUNCTION__); GLuint objectId = 0; GLuint groupId = 0; GLuint mtlId = 0; GLuint mtllibId = 0; string objectName; string groupName; string mtllibName; string mtlName; GLint program_loc_Ka = program.GetUniformLocation("Ka"); GLint program_loc_Kd = program.GetUniformLocation("Kd"); GLint program_loc_Ks = program.GetUniformLocation("Ks"); GLint program_loc_Ke = program.GetUniformLocation("Ke"); GLint program_loc_Tr = program.GetUniformLocation("Tr"); GLint program_loc_Tf = program.GetUniformLocation("Tf"); GLint program_loc_Ns = program.GetUniformLocation("Ns"); GLint program_loc_Ni = program.GetUniformLocation("Ni"); GLint program_loc_map_Ka = program.GetUniformLocation("map_Ka"); GLint program_loc_map_Kd = program.GetUniformLocation("map_Kd"); GLint program_loc_map_Ks = program.GetUniformLocation("map_Ks"); GLint program_loc_map_Ke = program.GetUniformLocation("map_Ke"); GLint program_loc_map_Tr = program.GetUniformLocation("map_Tr"); GLint program_loc_map_Tf = program.GetUniformLocation("map_Tf"); GLint program_loc_map_Ni = program.GetUniformLocation("map_Ni"); GLint program_loc_map_Ns = program.GetUniformLocation("map_Ns"); GLint program_loc_map_bump = program.GetUniformLocation("map_bump"); GLint program_loc_map_normal = program.GetUniformLocation("map_normal"); GLint program_loc_map_Ka_mix = program.GetUniformLocation("map_Ka_mix"); GLint program_loc_map_Kd_mix = program.GetUniformLocation("map_Kd_mix"); GLint program_loc_map_Ks_mix = program.GetUniformLocation("map_Ks_mix"); GLint program_loc_map_Ke_mix = program.GetUniformLocation("map_Ke_mix"); GLint program_loc_map_Tf_mix = program.GetUniformLocation("map_Tf_mix"); GLint program_loc_map_Tr_mix = program.GetUniformLocation("map_Tr_mix"); GLint program_loc_map_Ni_mix = program.GetUniformLocation("map_Ni_mix"); GLint program_loc_map_Ns_mix = program.GetUniformLocation("map_Ns_mix"); GLint program_loc_sphere_array = program.GetUniformLocation("Spheres"); GLint program_loc_sphere_count = program.GetUniformLocation("SpheresCount"); GLint program_loc_sphere_Ke = program.GetUniformLocation("SpheresKe"); vector spherePositions; vector sphereKe; for (auto sphIt = spheres.begin(); sphIt != spheres.end(); sphIt++) { if (spherePositions.size() > 8) break; Vector4f pos(0, 0, 0, 1); Vector4f radius(1, 0, 0, 1); pos = sphIt->second.transform * pos; radius = sphIt->second.transform * radius; radius = radius - pos; float length = radius.length(); pos.w = length; spherePositions.push_back(pos.x); spherePositions.push_back(pos.y); spherePositions.push_back(pos.z); spherePositions.push_back(pos.w); Vector3f Ke = materials.SetLibraryMaterial(sphIt->second.mtllibName, sphIt->second.mtlName)->Ke; sphereKe.push_back(Ke.r); sphereKe.push_back(Ke.g); sphereKe.push_back(Ke.b); sphereKe.push_back(1.0f); } glUniform4fv(program_loc_sphere_array, (int)spherePositions.size(), &spherePositions[0]); glUniform4fv(program_loc_sphere_Ke, (int)spherePositions.size(), &sphereKe[0]); glUniform1i(program_loc_sphere_count, (int)spherePositions.size()); // apply each material separately for (auto libIt = materials.begin(); libIt != materials.end(); libIt++) { SimpleMaterialLibrary &mtllib = libIt->second; mtllibName = mtllib.name; mtllibId = materials.GetLibraryId(mtllib.name); materials.SetLibrary(mtllib.name); if (debugging) cout << "SimpleSceneGraph::Render() -- using mtllib " << mtllib.name << endl; for (auto mtlIt = mtllib.mtls.begin(); mtlIt != mtllib.mtls.end(); mtlIt++) { mtlId = mtlIt->first; mtlName = materials.GetMaterialName(mtlId); while (mtlName.back() == '\0') mtlName.resize(mtlName.size() - 1); SimpleMaterial &mtl = mtlIt->second; materials.SetMaterial(mtlName); if (debugging) cout << "SimpleSceneGraph::Render() -- using mtl " << mtlId << endl; map textures; GLuint unit = 0; if (!mtl.map_Ka.empty()) textures["map_Ka"] = materials.GetTextureMap(mtl.map_Ka); if (!mtl.map_Kd.empty()) textures["map_Kd"] = materials.GetTextureMap(mtl.map_Kd); if (!mtl.map_Ks.empty()) textures["map_Ks"] = materials.GetTextureMap(mtl.map_Ks); if (!mtl.map_Ke.empty()) textures["map_Ke"] = materials.GetTextureMap(mtl.map_Ke); if (!mtl.map_Ns.empty()) textures["map_Ns"] = materials.GetTextureMap(mtl.map_Ns); if (!mtl.map_Tf.empty()) textures["map_Tf"] = materials.GetTextureMap(mtl.map_Tf); if (!mtl.map_Tr.empty()) textures["map_Tr"] = materials.GetTextureMap(mtl.map_Tr); if (!mtl.map_bump.empty()) textures["map_bump"] = materials.GetTextureMap(mtl.map_bump); if (!mtl.map_normal.empty()) textures["map_normal"] = materials.GetTextureMap(mtl.map_normal); if (mtl.map_Ka.empty()) glUniform1f(program_loc_map_Ka_mix, 0.0f); if (mtl.map_Kd.empty()) glUniform1f(program_loc_map_Kd_mix, 0.0f); if (mtl.map_Ks.empty()) glUniform1f(program_loc_map_Ks_mix, 0.0f); if (mtl.map_Ke.empty()) glUniform1f(program_loc_map_Ke_mix, 0.0f); if (mtl.map_Ns.empty()) glUniform1f(program_loc_map_Ns_mix, 0.0f); if (mtl.map_Tf.empty()) glUniform1f(program_loc_map_Tf_mix, 0.0f); if (mtl.map_Tr.empty()) glUniform1f(program_loc_map_Tr_mix, 0.0f); for (auto tmapIt = textures.begin(); tmapIt != textures.end(); tmapIt++) { SimpleMap *pMap = tmapIt->second; if (pMap) { pMap->unitId = 0;// unit; pMap->samplerId = pMap->textureObject.samplerObject.GetId(); pMap->textureId = pMap->textureObject.GetTextureId(); pMap->textureObject.Bind(unit, false); glTexParameterf(pMap->textureObject.GetTarget(), GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0); textures[mtlName] = pMap; unit++; GLint program_loc = program.GetUniformLocation(tmapIt->first.c_str()); if (program_loc >= 0) glUniform1i(program_loc, pMap->unitId); string tmp = tmapIt->first + "_mix"; program_loc = program.GetUniformLocation(tmp.c_str()); glUniform1f(program_loc, 1.0f); } } // Apply Material Uniforms to the program shader glUniform3fv(program_loc_Kd, 1, mtl.Kd.v); glUniform3fv(program_loc_Ks, 1, mtl.Ks.v); glUniform3fv(program_loc_Ke, 1, mtl.Ke.v); glUniform3fv(program_loc_Ka, 1, mtl.Ka.v); glUniform1fv(program_loc_Ni, 1, &mtl.Ni); glUniform1fv(program_loc_Ns, 1, &mtl.Ns); glUniform3fv(program_loc_Tr, 1, mtl.Tf.v); glUniform1fv(program_loc_Tf, 1, &mtl.Tr); for (auto geoIt = geometry.begin(); geoIt != geometry.end(); geoIt++) { SimpleGeometryGroup &geo = geoIt->second; if (debugging) cout << "SimpleSceneGraph::Render() -- using OBJ " << geo.objectName << endl; objectId = geo.objectId; groupId = 0; renderer.ApplyIdToMtlNames(mtlName, mtlIt->first); // Apply object specific uniforms like transformation matrices SimpleUniform ModelViewMatrix; ModelViewMatrix = geo.transform; program.ApplyUniform("NewModelViewMatrix", ModelViewMatrix); // No iterate through each object and render it with this material //renderer.RenderIf(objectId, groupId, mtllibId, mtlId, false); renderer.RenderIf(geo.objectName, "", geo.mtllibName, mtlName, false); } // Turn off textures for (auto tmapIt = textures.begin(); tmapIt != textures.end(); tmapIt++) { SimpleMap *pMap = tmapIt->second; if (pMap) { glutBindTexture(pMap->unitId, pMap->textureObject.GetTarget(), 0); GLint program_loc = program.GetUniformLocation(tmapIt->first.c_str()); if (program_loc >= 0) glUniform1i(program_loc, pMap->unitId); string tmp = tmapIt->first + "_mix"; program_loc = program.GetUniformLocation(tmp.c_str()); glUniform1f(program_loc, 0.0f); } } glutSetActiveTexture(GL_TEXTURE0); } } if (debugging) cout << "SimpleSceneGraph::Render() -- END\n"; }