*.log
_minted-report
.vim
+*.blend1
GLuint lightVao;
-Program *textureProg, *plainProg;
+Program *textureProg, *plainProg, *reflectProg;
Skybox *skybox;
glm::vec3 camPos = glm::vec3(0.0f, 0.0f, 0.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;
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);
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)); */
/* 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();
}
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",
};
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);
}
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);
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);
}
private:
GLuint progId;
aiColor4D ambient, diffuse, specular;
- ai_real shininess;
+ ai_real shininess, reflectivity;
struct Texture {
Texture(const std::string &file);
#include "model.hpp"
+#include "error.hpp"
#include <iostream>
#include <assimp/postprocess.h>
#include <glm/gtc/type_ptr.hpp>
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)) {
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);
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++) {
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");
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) {
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) {
#include <assimp/Importer.hpp>
#include "material.hpp"
#include "program.hpp"
+#include "skybox.hpp"
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);
private:
const Program program;
+ const Skybox skybox;
std::vector<Mesh> meshes;
Node *root;
--- /dev/null
+<?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
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);
+ }
+}
+
class Program {
public:
Program(const std::string vert, const std::string frag);
+ void validate() const;
GLuint progId;
};
#endif
--- /dev/null
+#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);
+}
--- /dev/null
+#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);
+}
#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++) {
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);
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));
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;
}
+#ifndef SKYBOX_HPP
+#define SKYBOX_HPP
+
#include <string>
#include <vector>
#include <GL/glew.h>
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
void main() {
texCoords = pos;
- gl_Position = projection * view * vec4(pos, 1);
+ vec4 fragPos = projection * view * vec4(pos, 1);
+ gl_Position = fragPos.xyww;
}
sampler2D specularMap;
float shininess;
+ float reflectivity;
+
bool hasTexture;
bool hasSpecularMap;
bool hasNormalMap;
};
-in vec3 defNormal;
+in vec3 defNormal, worldNormal;
in vec2 texCoord;
// These are all in tangent space
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;
}
#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;
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;
}