diff --git a/Controller.cpp b/Controller.cpp index 5f2d9b9..9a052c0 100644 --- a/Controller.cpp +++ b/Controller.cpp @@ -20,7 +20,7 @@ using namespace std; Controller::Controller(istream& scenegraphFile, Model& m,View& v): model(m), view(v) { initScenegraph(scenegraphFile); - globalCamera = new StationaryCamera(glm::vec3(50.0, 75.0, 100.0)); + globalCamera = new StationaryCamera(glm::vec3(0.0, 0.0, 30.0)); globalCamera->LookAt(glm::vec3(0.0,0.0,0.0)); cameras.push_back(globalCamera); diff --git a/View.cpp b/View.cpp index 7888865..f535865 100644 --- a/View.cpp +++ b/View.cpp @@ -96,9 +96,7 @@ void View::init(Callbacks *callbacks, Model& model) time = glfwGetTime(); deltaTime = 0; - if (useRaycast) - raycastRenderer = new sgraph::RaycastRenderer(modelview,"render.ppm"); - else + if (!useRaycast) renderer = new sgraph::GLScenegraphRenderer(modelview,objects,textureIds,shaderLocations); } @@ -188,6 +186,7 @@ float View::display(sgraph::IScenegraph *scenegraph, vector& cameras, C if (useRaycast) { modelview.push(glm::mat4(1.0)); modelview.top() *= activeCamera->GetViewMatrix(); + raycastRenderer = new sgraph::RaycastRenderer(modelview,lights,"render.ppm"); scenegraph->getRoot()->accept(raycastRenderer); raycastRenderer->raytrace(800, 800, modelview); modelview.pop(); diff --git a/scenegraphmodels/boxAndSphere.txt b/scenegraphmodels/boxAndSphere.txt index 3baac4f..b46f590 100644 --- a/scenegraphmodels/boxAndSphere.txt +++ b/scenegraphmodels/boxAndSphere.txt @@ -3,14 +3,20 @@ instance box models/box-outside.obj instance sphere models/sphere.obj #material -material mat -emission 0 0 0 +material bMat ambient 1 0 0 diffuse 1 0 0 specular 1 0 0 shininess 0 end-material +material sMat +ambient .3 0 .5 +diffuse .3 0 1 +specular .4 .2 .6 +shininess 50 +end-material + light globalLight ambient 0.3 0.3 0.3 diffuse 0.4 0.4 0.4 @@ -26,7 +32,7 @@ translate bTranslate bTranslate 7.5 0 0 rotate bRotate bRotate 30 .3 .15 .05 scale bScale bScale 10 10 10 leaf b one-box instanceof box -assign-material b mat +assign-material b bMat add-child b bScale add-child bScale bRotate add-child bRotate bTranslate @@ -34,7 +40,7 @@ add-child bRotate bTranslate translate sTranslate sTranslate -7.5 0 0 scale sScale sScale 5 5 5 leaf s one-sphere instanceof sphere -assign-material s mat +assign-material s sMat add-child s sScale add-child sScale sTranslate diff --git a/scenegraphmodels/sphere.txt b/scenegraphmodels/sphere.txt index 5682843..04e1c46 100644 --- a/scenegraphmodels/sphere.txt +++ b/scenegraphmodels/sphere.txt @@ -21,8 +21,8 @@ end-light #the root group node-1-0 root scale node-2-0 scale 5 5 5 -assign-light node-2-0 globalLight leaf node-3-0 one-sphere instanceof sphere #comment here? +assign-light node-3-0 globalLight assign-material node-3-0 mat-node-3-0 add-child node-3-0 node-2-0 diff --git a/sgraph/RaycastRenderer.hpp b/sgraph/RaycastRenderer.hpp index 1c4784e..1355b98 100644 --- a/sgraph/RaycastRenderer.hpp +++ b/sgraph/RaycastRenderer.hpp @@ -1,6 +1,7 @@ #ifndef _RAYCASTRENDERER_H_ #define _RAYCASTRENDERER_H_ +#include "Light.h" #include "Material.h" #include "SGNodeVisitor.h" #include "GroupNode.h" @@ -22,6 +23,7 @@ #include #include "../HitRecord.hpp" #include "glm/ext/quaternion_geometric.hpp" +#include "glm/geometric.hpp" #define GLM_ENABLE_EXPERIMENTAL #include @@ -68,9 +70,17 @@ namespace sgraph { * @param os the map of ObjectInstance objects * @param shaderLocations the shader locations for the program used to render */ - RaycastRenderer(stack& mv, string outfileLoc) + RaycastRenderer(stack& mv, vector& lights, string outfileLoc) : modelview(mv), - outfileLoc(outfileLoc) { } + lights(lights), + outfileLoc(outfileLoc) { + for (auto& light : this->lights) { + light.setPosition(modelview.top() * light.getPosition()); + glm::vec4 spotDir = glm::normalize(modelview.top() * light.getSpotDirection()); + light.setSpotDirection(spotDir.x, spotDir.y, spotDir.z); + light.setSpotAngle(cosf(light.getSpotCutoff())); + } + } /** * @brief Recur to the children for drawing @@ -266,6 +276,56 @@ namespace sgraph { } } + inline static glm::vec3 compMul(const glm::vec3& lhs, const glm::vec3& rhs) { + return glm::vec3(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z); + } + + glm::vec3 shade(HitRecord& hit) { + glm::vec3& fPosition = hit.intersection; + glm::vec3& fNormal = hit.normal; + glm::vec3 fColor(0,0,0); + glm::vec3 lightVec(0,0,0), viewVec(0,0,0), reflectVec(0,0,0); + glm::vec3 normalView(0,0,0); + glm::vec3 ambient(0,0,0), diffuse(0,0,0), specular(0,0,0); + float nDotL,rDotV; + + for (auto& light : lights) + { + if (light.getPosition().w!=0) + lightVec = glm::normalize(glm::vec3(light.getPosition()) - fPosition); + else + lightVec = glm::normalize(-glm::vec3(light.getPosition())); + + /* + glm::vec3 spotDir = light.getSpotDirection(); + if (glm::length(spotDir) > 0 && -glm::dot(spotDir,lightVec) < light.getSpotCutoff()) + { + continue; + } + */ + + glm::vec3 tNormal = fNormal; + normalView = glm::normalize(tNormal); + nDotL = glm::dot(normalView,lightVec); + + viewVec = -fPosition; + viewVec = glm::normalize(viewVec); + + reflectVec = glm::reflect(-lightVec,normalView); + reflectVec = glm::normalize(reflectVec); + + rDotV = max(glm::dot(reflectVec,viewVec),0.0f); + + ambient = compMul(hit.mat->getAmbient(), light.getAmbient()); + diffuse = compMul(hit.mat->getDiffuse(), light.getDiffuse()) * max(nDotL,0.f); + if (nDotL>0) + specular = compMul(hit.mat->getSpecular(), light.getSpecular()) * pow(rDotV,max(hit.mat->getShininess(), 1.f)); + fColor = fColor + ambient + diffuse + specular; + } + + return fColor; + } + void raytrace(int width, int height, stack& mv) { rayHits.resize(height); pixelData.resize(height); @@ -284,8 +344,9 @@ namespace sgraph { for (int jj = 0; jj < height; ++jj) { for (int ii = 0; ii < width; ++ii) { - if (rayHits[jj][ii].time < MaxFloat) { - pixelData[jj][ii] = glm::vec3(255, 255, 255); + HitRecord& hit = rayHits[jj][ii]; + if (hit.time < MaxFloat) { + pixelData[jj][ii] = shade(hit) * 255.f; } } } @@ -313,7 +374,8 @@ namespace sgraph { } private: - stack& modelview; + stack& modelview; + vector lights; // TODO: map textures; vector objs;