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<float> spherePositions;
vector<float> 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<string, SimpleMap*> 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";
}
Comments