Skip to content

Commit

Permalink
Added bump demo
Browse files Browse the repository at this point in the history
  • Loading branch information
nitronoid committed Mar 8, 2018
1 parent c92c565 commit 95c2653
Show file tree
Hide file tree
Showing 12 changed files with 285 additions and 7 deletions.
7 changes: 5 additions & 2 deletions Project.pro
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ HEADERS += \
include/MeshVBO.h \
include/MaterialWireframe.h \
include/MaterialFractal.h \
include/MaterialEnvMap.h
include/MaterialEnvMap.h \
include/MaterialBump.h


SOURCES += \
src/main.cpp \
Expand All @@ -60,7 +62,8 @@ SOURCES += \
src/MeshVBO.cpp \
src/MaterialWireframe.cpp \
src/MaterialFractal.cpp \
src/MaterialEnvMap.cpp
src/MaterialEnvMap.cpp \
src/MaterialBump.cpp

OTHER_FILES += \
$$files(shaders/*, true) \
Expand Down
Binary file added images/bricknormals.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/bricktexture.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/facenormals.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/facetexture.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
33 changes: 33 additions & 0 deletions include/MaterialBump.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#ifndef MATERIALBUMP_H
#define MATERIALBUMP_H

#include "Material.h"
#include <QOpenGLTexture>
#include <QImage>

class MaterialBump : public Material
{
public:
MaterialBump(const std::shared_ptr<Camera> &io_camera, const std::shared_ptr<ShaderLib> &io_shaderLib, std::array<glm::mat4, 3>* io_matrices) :
Material(io_camera, io_shaderLib, io_matrices)
{}
MaterialBump(const MaterialBump&) = default;
MaterialBump& operator=(const MaterialBump&) = default;
MaterialBump(MaterialBump&&) = default;
MaterialBump& operator=(MaterialBump&&) = default;
~MaterialBump() override = default;

virtual void init() override;

virtual void update() override;

virtual const char* shaderFileName() const override;

private:
void initColor();
void initNormal();
std::unique_ptr<QOpenGLTexture> m_colorMap;
std::unique_ptr<QOpenGLTexture> m_normalMap;
};

#endif // MATERIALBUMP_H
5 changes: 5 additions & 0 deletions shaderPrograms/bump.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"Name" : "Bump",
"Vertex" : "shaders/bump_vert.glsl",
"Fragment" : "shaders/bump_frag.glsl"
}
122 changes: 122 additions & 0 deletions shaders/bump_frag.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#version 430
uniform sampler2D NormalTexture;
uniform sampler2D ColourTexture;

// Set this property to change the scaling of the texture over the surface (higher means that the texture is repeated more frequently)
uniform float texCoordScale = 1.0;

// The output colour which will be output to the framebuffer
layout (location=0) out vec4 fragColour;

// Structure for holding light parameters
struct LightInfo
{
vec4 Position; // Light position in eye coords.
vec3 La; // Ambient light intensity
vec3 Ld; // Diffuse light intensity
vec3 Ls; // Specular light intensity
};

// We'll have a single light in the scene with some default values
uniform LightInfo Light = LightInfo(
vec4(2.0, 2.0, 10.0, 1.0), // position
vec3(0.2, 0.2, 0.2), // La
vec3(1.0, 1.0, 1.0), // Ld
vec3(1.0, 1.0, 1.0) // Ls
);

// The material properties of our object
struct MaterialInfo
{
vec3 Ka; // Ambient reflectivity
vec3 Kd; // Diffuse reflectivity
vec3 Ks; // Specular reflectivity
float Shininess; // Specular shininess factor
};

// The object has a material
uniform MaterialInfo Material = MaterialInfo(
vec3(0.1, 0.1, 0.1), // Ka
vec3(1.0, 1.0, 1.0), // Kd
vec3(1.0, 1.0, 1.0), // Ks
10.0); // Shininess

// Attributes passed on from the vertex shader
smooth in vec3 WSVertexPosition;
smooth in vec3 WSVertexNormal;
smooth in vec2 WSTexCoord;

uniform vec3 camPos;

/** From http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/
*/
mat4 rotationMatrix(vec3 axis, float angle)
{
//axis = normalize(axis);
float s = sin(angle);
float c = cos(angle);
float oc = 1.0 - c;
return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0,
oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0,
oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0,
0.0, 0.0, 0.0, 1.0);
}

/**
* Rotate a vector vec by using the rotation that transforms from src to tgt.
*/
vec3 rotateVector(vec3 src, vec3 tgt, vec3 vec)
{
float angle = acos(dot(src,tgt));

// Check for the case when src and tgt are the same vector, in which case
// the cross product will be ill defined.
if (angle == 0.0)
{
return vec;
}
vec3 axis = normalize(cross(src,tgt));
mat4 R = rotationMatrix(axis,angle);

// Rotate the vec by this rotation matrix
vec4 _norm = R*vec4(vec,1.0);
return _norm.xyz / _norm.w;
}

void main()
{
// Calculate the normal (this is the expensive bit in Phong)
vec3 n = normalize( WSVertexNormal );

// Calculate the view vector
vec3 v = normalize(vec3(camPos-WSVertexPosition));

// Extract the normal from the normal map (rescale to [-1,1]
vec3 tgt = normalize(texture(NormalTexture, WSTexCoord*texCoordScale).rgb * 2.0 - 1.0);

// The source is just up in the Z-direction
vec3 src = vec3(0.0, 0.0, 1.0);

// Perturb the normal according to the target
vec3 np = rotateVector(src, tgt, n);

// Calculate the light vector
vec3 s = normalize( vec3(Light.Position) - WSVertexPosition );

// Reflect the light about the surface normal
vec3 r = reflect( -s, np );

// Compute the light from the ambient, diffuse and specular components
vec3 lightColor = (
Light.La * Material.Ka +
Light.Ld * Material.Kd * max( dot(s, np), 0.0 ) +
Light.Ls * Material.Ks * pow( max( dot(r,v), 0.0 ), Material.Shininess ));

vec3 texColor = texture(ColourTexture, WSTexCoord*texCoordScale).rgb;

// Use the following shader for the correct value
fragColour = vec4(texColor*lightColor,1.0);
}



34 changes: 34 additions & 0 deletions shaders/bump_vert.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#version 430

// The modelview and projection matrices are no longer given in OpenGL 4.2
uniform mat4 MVP;
uniform mat4 MV;
uniform mat4 N; // This is the inverse transpose of the mv matrix

// The vertex position attribute
layout (location=0) in vec3 VertexPosition;

// The texture coordinate attribute
layout (location=1) in vec2 TexCoord;

// The vertex normal attribute
layout (location=2) in vec3 VertexNormal;

// These attributes are passed onto the shader (should they all be smoothed?)
smooth out vec3 WSVertexPosition;
smooth out vec3 WSVertexNormal;
smooth out vec2 WSTexCoord;

void main() {
// Transform the vertex normal by the inverse transpose modelview matrix
WSVertexNormal = normalize(vec3(N * vec4(VertexNormal, 1.0f)));

// Compute the unprojected vertex position
WSVertexPosition = vec3(MV * vec4(VertexPosition, 1.0) );

// Copy across the texture coordinates
WSTexCoord = TexCoord;

// Compute the position of the vertex
gl_Position = MVP * vec4(VertexPosition,1.0);
}
10 changes: 7 additions & 3 deletions src/DemoScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "MaterialPhong.h"
#include "MaterialFractal.h"
#include "MaterialEnvMap.h"
#include "MaterialBump.h"
#include <QOpenGLContext>

//-----------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -71,20 +72,23 @@ void DemoScene::keyPress(QKeyEvent* io_event)
//-----------------------------------------------------------------------------------------------------
void DemoScene::initMaterials()
{
m_materials.reserve(6);
m_materials.reserve(7);

m_materials.emplace_back(new MaterialBump(m_camera, m_shaderLib, &m_matrices));
m_materials.emplace_back(new MaterialEnvMap(m_camera, m_shaderLib, &m_matrices));
m_materials.emplace_back(new MaterialPhong(m_camera, m_shaderLib, &m_matrices));
m_materials.emplace_back(new MaterialPBR(m_camera, m_shaderLib, &m_matrices, {0.5f, 0.0f, 0.0f}, 1.0f, 1.0f, 0.5f, 1.0f));
m_materials.emplace_back(new MaterialPBR(m_camera, m_shaderLib, &m_matrices, {0.1f, 0.2f, 0.5f}, 0.5f, 1.0f, 0.4f, 0.2f));
m_materials.emplace_back(new MaterialWireframe(m_camera, m_shaderLib, &m_matrices));
m_materials.emplace_back(new MaterialFractal(m_camera, m_shaderLib, &m_matrices));
for (size_t i = 0; i < m_materials.size(); ++i)

for (auto& mat : m_materials)
{
auto& mat = m_materials[i];
auto name = m_shaderLib->loadShaderProg(mat->shaderFileName());
mat->setShaderName(name);
mat->apply();
}

m_materials[m_currentMaterial]->apply();
}
//-----------------------------------------------------------------------------------------------------
Expand Down
72 changes: 72 additions & 0 deletions src/MaterialBump.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include "MaterialBump.h"
#include "Scene.h"
#include "ShaderLib.h"

void MaterialBump::init()
{
initColor();
auto shaderPtr = m_shaderLib->getShader(m_shaderName);
shaderPtr->setUniformValue("ColourTexture", 0);

initNormal();
shaderPtr->setUniformValue("NormalTexture", 2);

update();
}

void MaterialBump::initColor()
{

using tex = QOpenGLTexture;
m_colorMap.reset(new QOpenGLTexture(QOpenGLTexture::Target2D));
auto map = QImage("images/bricktexture.jpg").mirrored().convertToFormat(QImage::Format_RGB888);
m_colorMap->setSize(map.width(), map.height(), map.depth());
m_colorMap->setFormat(tex::RGBFormat);
m_colorMap->allocateStorage();
m_colorMap->bind(0, tex::ResetTextureUnit);
m_colorMap->setData(tex::RGB, tex::UInt8, map.constBits());
m_colorMap->create();
m_colorMap->setWrapMode(tex::Repeat);
m_colorMap->setMinMagFilters(tex::Linear, tex::Linear);
}

void MaterialBump::initNormal()
{
using tex = QOpenGLTexture;
m_normalMap.reset(new QOpenGLTexture(QOpenGLTexture::Target2D));
auto map = QImage("images/bricknormals.jpg").mirrored().convertToFormat(QImage::Format_RGB888);
m_normalMap->setSize(map.width(), map.height(), map.depth());
m_normalMap->setFormat(tex::RGBFormat);
m_normalMap->allocateStorage();
m_normalMap->bind(2, tex::ResetTextureUnit);
m_normalMap->setData(tex::RGB, tex::UInt8, map.constBits());
m_normalMap->create();
m_normalMap->setWrapMode(tex::Repeat);
m_normalMap->setMinMagFilters(tex::Linear, tex::Linear);
}

void MaterialBump::update()
{
auto shaderPtr = m_shaderLib->getShader(m_shaderName);
auto eye = m_cam->getCameraEye();
shaderPtr->setUniformValue("camPos", QVector3D{eye.x, eye.y, eye.z});

// Scope the using declaration
{
using namespace SceneMatrices;
static constexpr std::array<const char*, 3> shaderUniforms = {{"M", "MVP", "N"}};
// Send all our matrices to the GPU
for (const auto matrixId : {MODEL_VIEW, PROJECTION, NORMAL})
{
// Convert from glm to Qt
QMatrix4x4 qmat(glm::value_ptr((*m_matrices)[matrixId]));
// Need to transpose the matrix as they both use different majors
shaderPtr->setUniformValue(shaderUniforms[matrixId], qmat.transposed());
}
}
}

const char* MaterialBump::shaderFileName() const
{
return "shaderPrograms/bump.json";
}
9 changes: 7 additions & 2 deletions src/MaterialEnvMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,15 @@ void MaterialEnvMap::init()

void MaterialEnvMap::initGlossMap()
{
m_glossMap.reset(new QOpenGLTexture(QImage("images/gloss.png")));
using tex = QOpenGLTexture;
m_glossMap.reset(new QOpenGLTexture(QOpenGLTexture::Target2D));
auto map = QImage("images/gloss.png").mirrored().convertToFormat(QImage::Format_RGBA8888);
m_glossMap->setSize(map.width(), map.height(), map.depth());
m_glossMap->setFormat(tex::RGBAFormat);
m_glossMap->allocateStorage();
m_glossMap->setData(tex::RGBA, tex::UInt8, map.constBits());
m_glossMap->create();
m_glossMap->bind(1);
using tex = QOpenGLTexture;
m_glossMap->setWrapMode(tex::Repeat);
m_glossMap->setMinMagFilters(tex::Linear, tex::Linear);
}
Expand Down

0 comments on commit 95c2653

Please sign in to comment.