Reflection
authorLuke Lau <luke_lau@icloud.com>
Thu, 8 Nov 2018 02:57:01 +0000 (02:57 +0000)
committerLuke Lau <luke_lau@icloud.com>
Thu, 8 Nov 2018 02:57:01 +0000 (02:57 +0000)
17 files changed:
.gitignore
main.cpp
material.cpp
material.hpp
model.cpp
model.hpp
models/mirrorCube.blend [new file with mode: 0644]
models/mirrorCube.dae [new file with mode: 0644]
program.cpp
program.hpp
reflectfrag.glsl [new file with mode: 0644]
reflectvert.glsl [new file with mode: 0644]
skybox.cpp
skybox.hpp
skyboxvert.glsl
texturefrag.glsl
texturevertex.glsl

index bc1c2f2..de0f0b8 100644 (file)
@@ -15,3 +15,4 @@ bin
 *.log
 _minted-report
 .vim
+*.blend1
index 613d679..4dd4e60 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -23,7 +23,7 @@ using namespace std;
 
 GLuint lightVao;
 
-Program *textureProg, *plainProg;
+Program *textureProg, *plainProg, *reflectProg;
 Skybox *skybox;
                          
 glm::vec3 camPos   = glm::vec3(0.0f, 0.0f,  0.0f);
@@ -31,8 +31,8 @@ glm::vec3 camFront = glm::vec3(0.0f, 0.0f, 1.0f);
 glm::vec3 camUp    = glm::vec3(0.0f, 1.0f,  0.0f);
 float yaw = 1.57, pitch = 0;
 bool doScale, doRotate, doTranslate;
-Model *chest;
-glm::vec3 lightPos(0);
+Model *chest, *mirrorCube;
+glm::vec3 lightPos(3);
 
 const int WIDTH = 800, HEIGHT = 600;
 const float ASPECT = (float)WIDTH / (float)HEIGHT;
@@ -88,8 +88,6 @@ void display() {
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
        float d = (float)glutGet(GLUT_ELAPSED_TIME) * 0.001f;
 
-       skybox->draw(projMat(), viewMat());
-
        glm::vec4 lightColor(1, 1, 1, 1);
 
        drawLight(d, lightPos, lightColor);
@@ -98,10 +96,10 @@ void display() {
        setProjectionAndViewUniforms(textureProg->progId);
        setLightColorAndPos(textureProg->progId, lightPos, lightColor);
 
-       Model::Node *top = chest->find("top");
-       top->model = glm::translate(glm::mat4(1), glm::vec3(0, 1, -1));
-       top->model = glm::rotate(top->model, sin(d / 2.5f) * 0.5f, glm::vec3(1, 0, 0));
-       top->model = glm::translate(top->model, glm::vec3(0, -1, 1));
+       /* Model::Node *top = chest->find("top"); */
+       /* top->model = glm::translate(glm::mat4(1), glm::vec3(0, 1, -1)); */
+       /* top->model = glm::rotate(top->model, sin(d / 2.5f) * 0.5f, glm::vec3(1, 0, 0)); */
+       /* top->model = glm::translate(top->model, glm::vec3(0, -1, 1)); */
        
        /* Model::Node *jewels = chest->find("jewels"); */
        /* jewels->model = glm::scale(glm::mat4(1), glm::vec3((sin(d) + 1.2f) / 2.f)); */
@@ -114,8 +112,11 @@ void display() {
        /* Model::Node *key = chest->find("key"); */
        /* key->model = glm::translate(glm::mat4(1), glm::vec3(0, 0, sin(d))); */
        
-       /* chest->getRoot()->model = glm::translate(glm::mat4(1), lightPos); */
-       chest->draw();
+       /* chest->draw(); */
+
+       mirrorCube->draw();
+
+       skybox->draw(projMat(), viewMat());
 
        glutSwapBuffers();
 }
@@ -136,29 +137,11 @@ void setupLightBuffers(GLuint progId) {
        glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
 }
 
-void validateProgram(GLuint progId) {
-       glValidateProgram(progId);
-       
-       GLint success;
-       glGetProgramiv(progId, GL_VALIDATE_STATUS, &success);
-       if (!success) {
-               GLchar log[1024];
-               glGetProgramInfoLog(progId, sizeof(log), NULL, log);
-               fprintf(stderr, "error: %s\n", log);
-               exit(1);
-       }
-}
-
 void init() {
        plainProg = new Program("plainvertex.glsl", "plainfrag.glsl");
        glUseProgram(plainProg->progId);
        setupLightBuffers(plainProg->progId);
-       validateProgram(plainProg->progId);
-
-       textureProg = new Program("texturevertex.glsl", "texturefrag.glsl");
-       glUseProgram(textureProg->progId);
-
-       chest = new Model("models/chest.dae", *textureProg);
+       plainProg->validate();
 
        std::vector<std::string> faces = {
                "models/skybox/right.jpg",
@@ -170,6 +153,11 @@ void init() {
        };
        skybox = new Skybox(faces);
 
+       textureProg = new Program("texturevertex.glsl", "texturefrag.glsl");
+       /* chest = new Model("models/chest.dae", *textureProg, *skybox); */
+
+       mirrorCube = new Model("models/mirrorCube.dae", *textureProg, *skybox);
+
        glEnable(GL_DEPTH_TEST); 
        glEnable(GL_CULL_FACE); 
 }
index 0e655a1..49af1d4 100644 (file)
@@ -7,17 +7,20 @@ Material::Material(const aiMaterial &ai, GLuint progId): progId(progId) {
                ai.GetTexture(aiTextureType_DIFFUSE, 0, &path);
                diffuseMap = new Texture(std::string(path.C_Str()));
        }
+
        if (ai.GetTextureCount(aiTextureType_SPECULAR) > 0) {
                aiString path;
                ai.GetTexture(aiTextureType_SPECULAR, 0, &path);
                specularMap = new Texture(std::string(path.C_Str()));
        }
+
        if (ai.GetTextureCount(aiTextureType_NORMALS) > 0) {
                aiString path;
                ai.GetTexture(aiTextureType_NORMALS, 0, &path);
                normalMap = new Texture(std::string(path.C_Str()));
        }
        ai.Get(AI_MATKEY_SHININESS, shininess);
+       ai.Get(AI_MATKEY_REFLECTIVITY, reflectivity);
        ai.Get(AI_MATKEY_COLOR_AMBIENT, ambient);
        ai.Get(AI_MATKEY_COLOR_DIFFUSE, diffuse);
        ai.Get(AI_MATKEY_COLOR_SPECULAR, specular);
@@ -36,23 +39,20 @@ void Material::bind() const {
        glUniform4f(glGetUniformLocation(progId, "material.diffuse"), diffuse.r, diffuse.g, diffuse.b, diffuse.a);
        glUniform4f(glGetUniformLocation(progId, "material.specular"), specular.r, specular.g, specular.b, specular.a);
        glUniform1f(glGetUniformLocation(progId, "material.shininess"), shininess);
+       glUniform1f(glGetUniformLocation(progId, "material.reflectivity"), reflectivity);
        glUniform1i(glGetUniformLocation(progId, "material.hasTexture"), diffuseMap != nullptr);
        glUniform1i(glGetUniformLocation(progId, "material.hasSpecularMap"), specularMap != nullptr);
        glUniform1i(glGetUniformLocation(progId, "material.hasNormalMap"), normalMap != nullptr);
        
-       if (diffuseMap) {
-               glUniform1i(glGetUniformLocation(progId, "material.diffuseMap"), 0);
-               glActiveTexture(GL_TEXTURE0);
-               glBindTexture(GL_TEXTURE_2D, diffuseMap->texId);
-       }
-       if (specularMap) {
-               glUniform1i(glGetUniformLocation(progId, "material.specularMap"), 1);
-               glActiveTexture(GL_TEXTURE1);
-               glBindTexture(GL_TEXTURE_2D, specularMap->texId);
-       }
-       if (normalMap) {
-               glUniform1i(glGetUniformLocation(progId, "material.normalMap"), 2);
+       glUniform1i(glGetUniformLocation(progId, "material.diffuseMap"), 2);
        glActiveTexture(GL_TEXTURE2);
-               glBindTexture(GL_TEXTURE_2D, normalMap->texId);
-       }
+       if (diffuseMap) glBindTexture(GL_TEXTURE_2D, diffuseMap->texId);
+
+       glUniform1i(glGetUniformLocation(progId, "material.specularMap"), 3);
+       glActiveTexture(GL_TEXTURE3);
+       if (specularMap) glBindTexture(GL_TEXTURE_2D, specularMap->texId);
+
+       glUniform1i(glGetUniformLocation(progId, "material.normalMap"), 4);
+       glActiveTexture(GL_TEXTURE4);
+       if (normalMap) glBindTexture(GL_TEXTURE_2D, normalMap->texId);
 }
index 06cd2d0..0fb6f5d 100644 (file)
@@ -13,7 +13,7 @@ class Material {
        private:
                GLuint progId;
                aiColor4D ambient, diffuse, specular;
-               ai_real shininess;
+               ai_real shininess, reflectivity;
 
                struct Texture {
                        Texture(const std::string &file);
index 524b913..c9ecdc1 100644 (file)
--- a/model.cpp
+++ b/model.cpp
@@ -1,4 +1,5 @@
 #include "model.hpp"
+#include "error.hpp"
 #include <iostream>
 #include <assimp/postprocess.h>
 #include <glm/gtc/type_ptr.hpp>
@@ -25,8 +26,8 @@ Model::Mesh::Mesh(const aiMesh *aiMesh, GLuint progId) {
                        aiVector3D b = aiMesh->mBitangents[i];
                        bitangents.push_back(glm::vec3(b.x, b.y, b.z));
                } else {
-                       tangents.push_back(glm::vec3(0));
-                       bitangents.push_back(glm::vec3(0));
+                       std::cerr << "Missing tangents: make sure blender has UV maps" << std::endl;
+                       exit(1);
                }
                // check for texture coord set 0
                if (aiMesh->HasTextureCoords(0)) {
@@ -59,13 +60,13 @@ Model::Mesh::Mesh(const aiMesh *aiMesh, GLuint progId) {
        GLuint vertexVbo = vbos[0], normalVbo = vbos[1], texCoordVbo = vbos[2], indicesVbo = vbos[3];
        GLuint tangentVbo = vbos[4], bitangentVbo = vbos[5];
        
-       GLuint posLoc = glGetAttribLocation(progId, "vPosition");
+       GLuint posLoc = glGetAttribLocation(progId, "pos");
        glBindBuffer(GL_ARRAY_BUFFER, vertexVbo);
        glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);
        glEnableVertexAttribArray(posLoc);
        glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
        
-       GLuint normalLoc = glGetAttribLocation(progId, "vNormal");
+       GLuint normalLoc = glGetAttribLocation(progId, "unscaledNormal");
        glBindBuffer(GL_ARRAY_BUFFER, normalVbo);
        glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), &normals[0], GL_STATIC_DRAW);
        glEnableVertexAttribArray(normalLoc);
@@ -91,7 +92,7 @@ Model::Mesh::Mesh(const aiMesh *aiMesh, GLuint progId) {
 
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesVbo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), &indices[0], GL_STATIC_DRAW);
-};
+}
 
 Model::Node::Node(const aiNode &node, GLuint progId): ai(node), progId(progId) {
        for (int i = 0; i < node.mNumMeshes; i++) {
@@ -113,6 +114,7 @@ glm::mat4 aiMatrixToMat4(aiMatrix4x4 from) {
 
 void Model::Node::draw(        const std::vector<Mesh> &meshes,
                                                const std::vector<Material> &materials,
+                                               const Skybox skybox,
                                                glm::mat4 parentTrans = glm::mat4(1)) const {
 
        GLuint modelLoc = glGetUniformLocation(progId, "model");
@@ -125,14 +127,20 @@ void Model::Node::draw(   const std::vector<Mesh> &meshes,
                Material material = materials[mesh.materialIndex];
                material.bind();
                
+               glUniform1i(glGetUniformLocation(progId, "skybox"), 5);
+               glActiveTexture(GL_TEXTURE5);
+               glBindTexture(GL_TEXTURE_CUBE_MAP, skybox.getTexture());
+               
                glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(m));
 
                glDrawElements(GL_TRIANGLES, mesh.numIndices, GL_UNSIGNED_INT, 0);
        }
-       for (Node *child: children) child->draw(meshes, materials, m);
+       for (Node *child: children) child->draw(meshes, materials, skybox, m);
 }
 
-Model::Model(const std::string &path, Program p): program(p) {
+Model::Model(const std::string &path, Program p, Skybox s): program(p), skybox(s) {
+       glUseProgram(p.progId);
+       
        const aiScene *scene = importer.ReadFile(path, 
                        aiProcess_Triangulate | aiProcess_CalcTangentSpace | aiProcess_GenNormals);
        if (!scene) {
@@ -155,7 +163,8 @@ Model::Model(const std::string &path, Program p): program(p) {
 
 void Model::draw() const {
        glUseProgram(program.progId);
-       root->draw(meshes, materials);
+       root->draw(meshes, materials, skybox);
+       program.validate();
 }
 
 Model::Node* Model::find(const std::string &name) {
index de8e27f..e0c8a2d 100644 (file)
--- a/model.hpp
+++ b/model.hpp
@@ -9,6 +9,7 @@
 #include <assimp/Importer.hpp>
 #include "material.hpp"
 #include "program.hpp"
+#include "skybox.hpp"
 
 class Model {
 
@@ -19,13 +20,13 @@ class Model {
        };
        
        public:
-               Model(const std::string &path, Program p);
+               Model(const std::string &path, Program p, Skybox s);
                void draw() const;
 
                class Node {
                        public:
                                Node(const aiNode &aiNode, GLuint progId);
-                               void draw(const std::vector<Mesh> &meshes, const std::vector<Material> &materials, glm::mat4 parentModel) const;
+                               void draw(const std::vector<Mesh> &meshes, const std::vector<Material> &materials, const Skybox s, glm::mat4 parentModel) const;
                                const std::vector<Node*> &getChildren() const { return children; }
                                Node* findNode(const aiNode &aiNode);
                                glm::mat4 model = glm::mat4(1);
@@ -42,6 +43,7 @@ class Model {
        
        private:
                const Program program;
+               const Skybox skybox;
                
                std::vector<Mesh> meshes;
                Node *root;
diff --git a/models/mirrorCube.blend b/models/mirrorCube.blend
new file mode 100644 (file)
index 0000000..77d1d4e
Binary files /dev/null and b/models/mirrorCube.blend differ
diff --git a/models/mirrorCube.dae b/models/mirrorCube.dae
new file mode 100644 (file)
index 0000000..d84bd4b
--- /dev/null
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="utf-8"?>
+<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <asset>
+    <contributor>
+      <author>Blender User</author>
+      <authoring_tool>Blender 2.79.0 commit date:2018-03-22, commit time:14:10, hash:f4dc9f9</authoring_tool>
+    </contributor>
+    <created>2018-11-08T02:49:10</created>
+    <modified>2018-11-08T02:49:10</modified>
+    <unit name="meter" meter="1"/>
+    <up_axis>Z_UP</up_axis>
+  </asset>
+  <library_cameras>
+    <camera id="Camera-camera" name="Camera">
+      <optics>
+        <technique_common>
+          <perspective>
+            <xfov sid="xfov">49.13434</xfov>
+            <aspect_ratio>1.777778</aspect_ratio>
+            <znear sid="znear">0.1</znear>
+            <zfar sid="zfar">100</zfar>
+          </perspective>
+        </technique_common>
+      </optics>
+      <extra>
+        <technique profile="blender">
+          <shiftx sid="shiftx" type="float">0</shiftx>
+          <shifty sid="shifty" type="float">0</shifty>
+          <YF_dofdist sid="YF_dofdist" type="float">0</YF_dofdist>
+        </technique>
+      </extra>
+    </camera>
+  </library_cameras>
+  <library_lights>
+    <light id="Lamp-light" name="Lamp">
+      <technique_common>
+        <point>
+          <color sid="color">1 1 1</color>
+          <constant_attenuation>1</constant_attenuation>
+          <linear_attenuation>0</linear_attenuation>
+          <quadratic_attenuation>0.00111109</quadratic_attenuation>
+        </point>
+      </technique_common>
+      <extra>
+        <technique profile="blender">
+          <type sid="type" type="int">0</type>
+          <flag sid="flag" type="int">0</flag>
+          <mode sid="mode" type="int">8192</mode>
+          <gamma sid="blender_gamma" type="float">1</gamma>
+          <red sid="red" type="float">1</red>
+          <green sid="green" type="float">1</green>
+          <blue sid="blue" type="float">1</blue>
+          <shadow_r sid="blender_shadow_r" type="float">0</shadow_r>
+          <shadow_g sid="blender_shadow_g" type="float">0</shadow_g>
+          <shadow_b sid="blender_shadow_b" type="float">0</shadow_b>
+          <energy sid="blender_energy" type="float">1</energy>
+          <dist sid="blender_dist" type="float">29.99998</dist>
+          <spotsize sid="spotsize" type="float">75</spotsize>
+          <spotblend sid="spotblend" type="float">0.15</spotblend>
+          <halo_intensity sid="blnder_halo_intensity" type="float">1</halo_intensity>
+          <att1 sid="att1" type="float">0</att1>
+          <att2 sid="att2" type="float">1</att2>
+          <falloff_type sid="falloff_type" type="int">2</falloff_type>
+          <clipsta sid="clipsta" type="float">1.000799</clipsta>
+          <clipend sid="clipend" type="float">30.002</clipend>
+          <bias sid="bias" type="float">1</bias>
+          <soft sid="soft" type="float">3</soft>
+          <compressthresh sid="compressthresh" type="float">0.04999995</compressthresh>
+          <bufsize sid="bufsize" type="int">2880</bufsize>
+          <samp sid="samp" type="int">3</samp>
+          <buffers sid="buffers" type="int">1</buffers>
+          <filtertype sid="filtertype" type="int">0</filtertype>
+          <bufflag sid="bufflag" type="int">0</bufflag>
+          <buftype sid="buftype" type="int">2</buftype>
+          <ray_samp sid="ray_samp" type="int">1</ray_samp>
+          <ray_sampy sid="ray_sampy" type="int">1</ray_sampy>
+          <ray_sampz sid="ray_sampz" type="int">1</ray_sampz>
+          <ray_samp_type sid="ray_samp_type" type="int">0</ray_samp_type>
+          <area_shape sid="area_shape" type="int">1</area_shape>
+          <area_size sid="area_size" type="float">0.1</area_size>
+          <area_sizey sid="area_sizey" type="float">0.1</area_sizey>
+          <area_sizez sid="area_sizez" type="float">1</area_sizez>
+          <adapt_thresh sid="adapt_thresh" type="float">0.000999987</adapt_thresh>
+          <ray_samp_method sid="ray_samp_method" type="int">1</ray_samp_method>
+          <shadhalostep sid="shadhalostep" type="int">0</shadhalostep>
+          <sun_effect_type sid="sun_effect_type" type="int">0</sun_effect_type>
+          <skyblendtype sid="skyblendtype" type="int">1</skyblendtype>
+          <horizon_brightness sid="horizon_brightness" type="float">1</horizon_brightness>
+          <spread sid="spread" type="float">1</spread>
+          <sun_brightness sid="sun_brightness" type="float">1</sun_brightness>
+          <sun_size sid="sun_size" type="float">1</sun_size>
+          <backscattered_light sid="backscattered_light" type="float">1</backscattered_light>
+          <sun_intensity sid="sun_intensity" type="float">1</sun_intensity>
+          <atm_turbidity sid="atm_turbidity" type="float">2</atm_turbidity>
+          <atm_extinction_factor sid="atm_extinction_factor" type="float">1</atm_extinction_factor>
+          <atm_distance_factor sid="atm_distance_factor" type="float">1</atm_distance_factor>
+          <skyblendfac sid="skyblendfac" type="float">1</skyblendfac>
+          <sky_exposure sid="sky_exposure" type="float">1</sky_exposure>
+          <sky_colorspace sid="sky_colorspace" type="int">0</sky_colorspace>
+        </technique>
+      </extra>
+    </light>
+  </library_lights>
+  <library_images>
+    <image id="brickwall_normal_jpg" name="brickwall_normal_jpg">
+      <init_from>brickwall_normal.jpg</init_from>
+    </image>
+  </library_images>
+  <library_effects>
+    <effect id="Mirror-effect">
+      <profile_COMMON>
+        <newparam sid="brickwall_normal_jpg-surface">
+          <surface type="2D">
+            <init_from>brickwall_normal_jpg</init_from>
+          </surface>
+        </newparam>
+        <newparam sid="brickwall_normal_jpg-sampler">
+          <sampler2D>
+            <source>brickwall_normal_jpg-surface</source>
+          </sampler2D>
+        </newparam>
+        <technique sid="common">
+          <phong>
+            <emission>
+              <color sid="emission">0 0 0 1</color>
+            </emission>
+            <ambient>
+              <color sid="ambient">0 0 0 1</color>
+            </ambient>
+            <diffuse>
+              <color sid="diffuse">0.64 0.005287599 0.4252137 1</color>
+            </diffuse>
+            <specular>
+              <color sid="specular">0.5 0.5 0.5 1</color>
+            </specular>
+            <shininess>
+              <float sid="shininess">50</float>
+            </shininess>
+            <reflective>
+              <color>1 1 1 1</color>
+            </reflective>
+            <reflectivity>
+              <float>1</float>
+            </reflectivity>
+            <index_of_refraction>
+              <float sid="index_of_refraction">1</float>
+            </index_of_refraction>
+          </phong>
+          <extra>
+            <technique profile="FCOLLADA">
+              <bump>
+                <texture texture="brickwall_normal_jpg-sampler" texcoord="UVMap"/>
+              </bump>
+            </technique>
+          </extra>
+        </technique>
+      </profile_COMMON>
+    </effect>
+  </library_effects>
+  <library_materials>
+    <material id="Mirror-material" name="Mirror">
+      <instance_effect url="#Mirror-effect"/>
+    </material>
+  </library_materials>
+  <library_geometries>
+    <geometry id="Cube-mesh" name="Cube">
+      <mesh>
+        <source id="Cube-mesh-positions">
+          <float_array id="Cube-mesh-positions-array" count="24">1 1 -1 1 -1 -1 -1 -0.9999998 -1 -0.9999997 1 -1 1 0.9999995 1 0.9999994 -1.000001 1 -1 -0.9999997 1 -1 1 1</float_array>
+          <technique_common>
+            <accessor source="#Cube-mesh-positions-array" count="8" stride="3">
+              <param name="X" type="float"/>
+              <param name="Y" type="float"/>
+              <param name="Z" type="float"/>
+            </accessor>
+          </technique_common>
+        </source>
+        <source id="Cube-mesh-normals">
+          <float_array id="Cube-mesh-normals-array" count="36">0 0 -1 0 0 1 1 0 -2.38419e-7 0 -1 -4.76837e-7 -1 2.38419e-7 -1.49012e-7 2.68221e-7 1 2.38419e-7 0 0 -1 0 0 1 1 -5.96046e-7 3.27825e-7 -4.76837e-7 -1 0 -1 2.38419e-7 -1.19209e-7 2.08616e-7 1 0</float_array>
+          <technique_common>
+            <accessor source="#Cube-mesh-normals-array" count="12" stride="3">
+              <param name="X" type="float"/>
+              <param name="Y" type="float"/>
+              <param name="Z" type="float"/>
+            </accessor>
+          </technique_common>
+        </source>
+        <source id="Cube-mesh-map-0">
+          <float_array id="Cube-mesh-map-0-array" count="72">0 0 1 1 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 1 1 0 1 1 0 0 1 0 0 0 0 1 0 1 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 0 0 1 0 1 1 1 0 1 1 0 1</float_array>
+          <technique_common>
+            <accessor source="#Cube-mesh-map-0-array" count="36" stride="2">
+              <param name="S" type="float"/>
+              <param name="T" type="float"/>
+            </accessor>
+          </technique_common>
+        </source>
+        <vertices id="Cube-mesh-vertices">
+          <input semantic="POSITION" source="#Cube-mesh-positions"/>
+        </vertices>
+        <triangles material="Mirror-material" count="12">
+          <input semantic="VERTEX" source="#Cube-mesh-vertices" offset="0"/>
+          <input semantic="NORMAL" source="#Cube-mesh-normals" offset="1"/>
+          <input semantic="TEXCOORD" source="#Cube-mesh-map-0" offset="2" set="0"/>
+          <p>0 0 0 2 0 1 3 0 2 7 1 3 5 1 4 4 1 5 4 2 6 1 2 7 0 2 8 5 3 9 2 3 10 1 3 11 2 4 12 7 4 13 3 4 14 0 5 15 7 5 16 4 5 17 0 6 18 1 6 19 2 6 20 7 7 21 6 7 22 5 7 23 4 8 24 5 8 25 1 8 26 5 9 27 6 9 28 2 9 29 2 10 30 6 10 31 7 10 32 0 11 33 3 11 34 7 11 35</p>
+        </triangles>
+      </mesh>
+    </geometry>
+  </library_geometries>
+  <library_controllers/>
+  <library_visual_scenes>
+    <visual_scene id="Scene" name="Scene">
+      <node id="Camera" name="Camera" type="NODE">
+        <matrix sid="transform">0.6859207 -0.3240135 0.6515582 7.481132 0.7276763 0.3054208 -0.6141704 -6.50764 0 0.8953956 0.4452714 5.343665 0 0 0 1</matrix>
+        <instance_camera url="#Camera-camera"/>
+      </node>
+      <node id="Lamp" name="Lamp" type="NODE">
+        <matrix sid="transform">-0.2908646 -0.7711008 0.5663932 4.076245 0.9551712 -0.1998834 0.2183912 1.005454 -0.05518906 0.6045247 0.7946723 5.903862 0 0 0 1</matrix>
+        <instance_light url="#Lamp-light"/>
+      </node>
+      <node id="Cube" name="Cube" type="NODE">
+        <matrix sid="transform">1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1</matrix>
+        <instance_geometry url="#Cube-mesh" name="Cube">
+          <bind_material>
+            <technique_common>
+              <instance_material symbol="Mirror-material" target="#Mirror-material"/>
+            </technique_common>
+          </bind_material>
+        </instance_geometry>
+      </node>
+    </visual_scene>
+  </library_visual_scenes>
+  <scene>
+    <instance_visual_scene url="#Scene"/>
+  </scene>
+</COLLADA>
\ No newline at end of file
index b1f2ede..d6adf06 100644 (file)
@@ -48,3 +48,17 @@ Program::Program(const string vertexShader, const string fragmentShader) {
                exit(1);
        }
 }
+
+void Program::validate() const {
+       glValidateProgram(progId);
+       
+       GLint success;
+       glGetProgramiv(progId, GL_VALIDATE_STATUS, &success);
+       if (!success) {
+               GLchar log[1024];
+               glGetProgramInfoLog(progId, sizeof(log), NULL, log);
+               fprintf(stderr, "error: %s\n", log);
+               exit(1);
+       }
+}
+
index 0436338..3fa8879 100644 (file)
@@ -5,6 +5,7 @@
 class Program {
        public:
                Program(const std::string vert, const std::string frag);
+               void validate() const;
                GLuint progId;
 };
 #endif
diff --git a/reflectfrag.glsl b/reflectfrag.glsl
new file mode 100644 (file)
index 0000000..9506153
--- /dev/null
@@ -0,0 +1,15 @@
+#version 330
+
+in vec3 fragPos;
+in vec3 normal;
+
+uniform vec3 viewPos;
+uniform samplerCube skybox;
+
+out vec4 fragColor;
+
+void main() {
+       vec3 I = normalize(fragPos - viewPos);
+       vec3 R = reflect(I, normalize(normal));
+       fragColor = vec4(texture(skybox, R).rgb, 1);
+}
diff --git a/reflectvert.glsl b/reflectvert.glsl
new file mode 100644 (file)
index 0000000..43a4d3d
--- /dev/null
@@ -0,0 +1,15 @@
+#version 330
+
+in vec3 pos;
+in vec3 unscaledNormal;
+
+out vec3 fragPos;
+out vec3 normal;
+
+uniform mat4 model, view, projection;
+
+void main() {
+       normal = mat3(inverse(transpose(model))) * unscaledNormal;
+       fragPos = vec3(model * vec4(pos, 1));
+       gl_Position = projection * view * vec4(fragPos, 1);
+}
index bd097cb..79ce9d0 100644 (file)
@@ -1,13 +1,12 @@
 #include "shapes.hpp"
 #include "skybox.hpp"
 #include "image.hpp"
-#include <GL/glew.h>
 #include <glm/gtc/type_ptr.hpp>
        
 Skybox::Skybox(const std::vector<std::string> faces): program("skyboxvert.glsl", "skyboxfrag.glsl") {
-       glUseProgram(program.progId);
        glGenTextures(1, &texId);
        glBindTexture(GL_TEXTURE_CUBE_MAP, texId);
+       glDepthFunc(GL_LEQUAL);
 
        int width, height, numChans;
        for (int i = 0; i < faces.size(); i++) {
@@ -30,6 +29,9 @@ Skybox::Skybox(const std::vector<std::string> faces): program("skyboxvert.glsl",
 
        auto vertices = cube();
 
+       //reverse so facing inside out
+       std::reverse(vertices.begin(), vertices.end());
+
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);
        
@@ -37,26 +39,11 @@ Skybox::Skybox(const std::vector<std::string> faces): program("skyboxvert.glsl",
        glEnableVertexAttribArray(posLoc);
        glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
 }
-void validatePrograms(GLuint progId) {
-       glValidateProgram(progId);
-       
-       GLint success;
-       glGetProgramiv(progId, GL_VALIDATE_STATUS, &success);
-       if (!success) {
-               GLchar log[1024];
-               glGetProgramInfoLog(progId, sizeof(log), NULL, log);
-               fprintf(stderr, "error: %s\n", log);
-               exit(1);
-       }
-}
 
 void Skybox::draw(glm::mat4 proj, glm::mat4 view) const {
        glUseProgram(program.progId);
 
-       glDepthMask(GL_FALSE);
-       glDisable(GL_CULL_FACE);
        glBindVertexArray(vao);
-       validatePrograms(program.progId);
 
        GLuint projLoc = glGetUniformLocation(program.progId, "projection");
        glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(proj));
@@ -65,8 +52,11 @@ void Skybox::draw(glm::mat4 proj, glm::mat4 view) const {
        view = glm::mat4(glm::mat3(view));
        glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
 
+       glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_CUBE_MAP, texId);
        glDrawArrays(GL_TRIANGLES, 0, 36);
-       glEnable(GL_CULL_FACE);
-       glDepthMask(GL_TRUE);
+}
+
+GLuint Skybox::getTexture() const {
+       return texId;
 }
index f1ac4ee..759ce7a 100644 (file)
@@ -1,3 +1,6 @@
+#ifndef SKYBOX_HPP
+#define SKYBOX_HPP
+
 #include <string>
 #include <vector>
 #include <GL/glew.h>
@@ -7,7 +10,10 @@ class Skybox {
        public:
                Skybox(const std::vector<std::string> faces);
                void draw(glm::mat4 proj, glm::mat4 view) const;
+               GLuint getTexture() const;
        private:
                GLuint texId, vao;
                const Program program;
 };
+
+#endif
index f1ba729..4946c73 100644 (file)
@@ -8,5 +8,6 @@ uniform mat4 view;
 
 void main() {
        texCoords = pos;
-       gl_Position = projection * view * vec4(pos, 1);
+       vec4 fragPos = projection * view * vec4(pos, 1);
+       gl_Position = fragPos.xyww;
 }
index 94bda7f..2a3de55 100644 (file)
@@ -8,6 +8,8 @@ struct Material {
        sampler2D specularMap;
        float shininess;
 
+       float reflectivity;
+       
        bool hasTexture;
        bool hasSpecularMap;
 
@@ -15,7 +17,7 @@ struct Material {
        bool hasNormalMap;
 };
 
-in vec3 defNormal;
+in vec3 defNormal, worldNormal;
 in vec2 texCoord;
 
 // These are all in tangent space
@@ -23,47 +25,50 @@ in vec3 lightPos;
 in vec3 viewPos;
 in vec3 fragPos;
 
+in vec3 worldViewPos, worldFragPos;
+
 uniform vec4 lightColor;
 
 uniform Material material;
 
+uniform samplerCube skybox;
+
 out vec4 FragColor;
 
-void main() {
+vec4 reflection(vec3 normal) {
+       vec3 I = normalize(worldFragPos - worldViewPos);
+       vec3 R = reflect(I, normalize(normal));
+       return vec4(texture(skybox, R).rgb, 1);
+}
 
-       vec3 normal;
-       if (material.hasNormalMap) {
-               normal = texture(material.normalMap, texCoord).rgb;
+void main() {
+       vec3 normal = texture(material.normalMap, texCoord).rgb;
        normal = normalize(normal * 2 - 1);
-       } else {
+       if (!material.hasNormalMap)
                normal = defNormal;
-       }
 
        vec3 lightDir = normalize(lightPos - fragPos);
        
-       vec4 diffTex;
-       if (material.hasTexture)
-               diffTex = texture(material.diffuseMap, texCoord);
-       else
-               diffTex = vec4(1);
+       vec4 diffTex = texture(material.diffuseMap, texCoord);
+       if (!material.hasTexture)
+               diffTex = material.diffuse;
+       
+       diffTex = mix(diffTex, reflection(worldNormal), material.reflectivity);
        
        vec4 ambient = material.ambient * diffTex;
 
-       vec4 diffuse = max(0, dot(lightDir, normal)) * material.diffuse * diffTex;
+       vec4 diffuse = max(0, dot(lightDir, normal)) * diffTex;
 
        vec3 viewDir = normalize(viewPos - fragPos);
        vec3 reflectDir = reflect(-lightDir, normal);
 
-       vec4 specTex;
-       if (material.hasSpecularMap)
-               specTex = texture(material.specularMap, texCoord);
-       else
-               specTex = vec4(1);
+       vec4 specTex = texture(material.specularMap, texCoord);
+       if (!material.hasSpecularMap)
+               specTex = material.specular;
 
-       vec4 specular = pow(max(0, dot(viewDir, reflectDir)), material.shininess) * material.specular * specTex;
+       vec4 specular = pow(max(0, dot(viewDir, reflectDir)), material.shininess) * specTex;
 
-       vec4 lighting = (ambient + diffuse + specular) * lightColor;
+       FragColor = (ambient + diffuse + specular) * lightColor;
 
-       FragColor = lighting;
 }
 
index 684b9b9..06535cf 100644 (file)
@@ -1,7 +1,7 @@
 #version 330
-in vec3 vPosition;
+in vec3 pos;
 in vec4 vColor;
-in vec3 vNormal;
+in vec3 unscaledNormal;
 in vec3 tangent;
 in vec3 bitangent;
 in vec2 vTexCoord;
@@ -10,31 +10,37 @@ uniform mat4 model;
 uniform mat4 view;
 uniform mat4 projection;
 
-out vec3 defNormal;
+out vec3 defNormal, worldNormal;
 out vec2 texCoord;
 
 uniform vec3 vLightPos;
 uniform vec3 vViewPos;
 
-out vec3 lightPos;
-out vec3 viewPos;
-out vec3 fragPos;
+out vec3 lightPos, viewPos, fragPos;
+out vec3 worldViewPos, worldFragPos;
 
 void main() {
-       vec4 pos = model * vec4(vPosition, 1.f);
+       vec4 worldPos = model * vec4(pos, 1.f);
        texCoord = vTexCoord;
 
        //tangent space stuff
        vec3 T = normalize(vec3(model * vec4(tangent,   0.0)));
        vec3 B = normalize(vec3(model * vec4(bitangent, 0.0)));
-       vec3 N = normalize(vec3(model * vec4(vNormal,    0.0)));
+       vec3 N = normalize(vec3(model * vec4(unscaledNormal,    0.0)));
        // convert TBN to world->tangent space
        mat3 TBN = transpose(mat3(T, B, N));
 
        lightPos = TBN * vLightPos;
        viewPos = TBN * vViewPos;
-       fragPos = TBN * vec3(pos);
-       defNormal = TBN * mat3(transpose(inverse(model))) * vNormal;
+       fragPos = TBN * vec3(worldPos);
 
-       gl_Position = projection * view * pos;
+       worldViewPos = vViewPos;
+       worldFragPos = vec3(worldPos);
+
+       vec3 normal = mat3(transpose(inverse(model))) * unscaledNormal;
+
+       defNormal = TBN * normal;
+       worldNormal = normal;
+       
+       gl_Position = projection * view * worldPos;
 }