Skip to content
Snippets Groups Projects
Commit 0a9b8596 authored by Joseph Walton-Rivers's avatar Joseph Walton-Rivers
Browse files

support for phong materials

parent 035a4566
No related branches found
No related tags found
No related merge requests found
#version 330 core
// based on http://www.opengl-tutorial.org, WTFPL
// features lighting additions from https://learnopengl.com/, CC BY-NC 4.0
struct Material {
vec3 ambient;
vec3 diffuse;
vec3 specular;
float shininess;
};
uniform Material material;
uniform vec3 lightPos;
uniform vec3 objColour;
in vec3 normal;
......@@ -16,14 +25,8 @@ out vec4 FragColor;
void main()
{
vec3 lightColour = vec3( 1.0, 1.0, 1.0 );
vec3 objColour = vec3(1.0f, 0.6f, 0.2f);
float lightPower = 200.0;
// material colours
vec3 matDiff = vec3(1.0, 0.6, 0.2 );
vec3 matAmb = vec3(0.1) * matDiff;
vec3 matSpec = vec3(0.3);
vec3 n = normalize( normal_cs );
vec3 l = normalize( lightdir_cs );
float distance = length( lightPos - pos_ws );
......@@ -31,12 +34,12 @@ void main()
vec3 e = normalize( eyedir_cs );
vec3 r = reflect( -l, n );
float cosAlpha = clamp( dot(e, r), 0, 1);
float cosTheta = clamp( dot( n, l ), 0, 1 );
vec3 colour =
( matAmb ) +
( matDiff * lightColour * lightPower * cosTheta / ( distance*distance ) ) +
( matSpec * lightColour * lightPower * pow( cosAlpha, 5 ) / (distance*distance) );
vec3 colour =
( material.ambient * vec3(0.1) ) +
( material.diffuse * vec3(0.5) * lightColour * lightPower * cosTheta / ( distance*distance ) ) +
( material.specular * lightColour * lightPower * pow( cosAlpha, material.shininess * 128 ) / (distance*distance) );
FragColor = vec4(colour, 1);
}
......@@ -20,6 +20,8 @@
#include "rollball.hpp"
#include "fggl/gfx/camera.hpp"
#include "fggl/gfx/phong.hpp"
#include "fggl/input/camera_input.h"
#include "fggl/util/service.h"
#include "fggl/ecs3/prototype/loader.hpp"
......@@ -40,11 +42,22 @@ static void setup_prefabs(fggl::ecs3::World& world, Prefabs& prefabs) {
// player (cube because my sphere function doesn't exist yet
prefabs.player = world.findPrototype("player");
world.add<fggl::phys::Dynamics>(prefabs.player);
auto* material = world.add< fggl::gfx::PhongMaterial >( prefabs.player );
material->ambient = fggl::math::vec3(0.25F, 0.25F, 0.25F);
material->diffuse = fggl::math::vec3(0.4F, 0.4F, 0.4F);
material->specular = fggl::math::vec3(0.774597F, 0.774597F, 0.774597F);
material->shininess = 0.6F;
}
{
// collectable
prefabs.collectable = world.findPrototype("collectable");
auto* material = world.add< fggl::gfx::PhongMaterial >( prefabs.collectable );
material->ambient = fggl::math::vec3(0.0215F, 0.1754F, 0.0215F);
material->diffuse = fggl::math::vec3(0.007568F, 0.61424F, 0.07568F);
material->specular = fggl::math::vec3(0.633F, 0.727811F, 0.633F);
material->shininess = 0.6F;
// we need both of these for callbacks to trigger.
world.add<fggl::phys::CollisionCallbacks>(prefabs.collectable);
......@@ -204,6 +217,10 @@ namespace demo {
}
// rotation
float closestDistance = FLT_MAX;
fggl::ecs::entity_t closestEntity = fggl::ecs::NULL_ENTITY;
auto playerPos = world.get<fggl::math::Transform>(state.player)->origin();
for ( auto& entity : state.collectables ) {
if ( world.alive(entity) ) {
auto* transform = world.get<fggl::math::Transform>(entity);
......@@ -211,6 +228,15 @@ namespace demo {
// rotate the cubes
fggl::math::vec3 angles{1.0F, 2.0F, 3.0F};
transform->rotateEuler( angles * (60.0F / 1000) );
auto distance = glm::distance(transform->origin(), playerPos);
if ( distance < closestDistance) {
closestDistance = distance;
closestEntity = entity;
}
//auto* renderer = world.get<fggl::data::StaticMesh>( entity );
//renderer->hintColour = fggl::math::vec3(1.0F, 1.0F, 1.0F);
}
}
state.time += (60.0f / 1000);
......
......@@ -26,6 +26,8 @@
#include "fggl/data/heightmap.h"
#include "fggl/gfx/camera.hpp"
#include "fggl/gfx/phong.hpp"
#include <spdlog/spdlog.h>
namespace fggl::gfx::ogl4 {
......@@ -161,6 +163,19 @@ namespace fggl::gfx::ogl4 {
shader->setUniformMtx(shader->uniform("view"), viewMatrix);
shader->setUniformMtx(shader->uniform("projection"), projectionMatrix);
auto* material = world.tryGet<fggl::gfx::PhongMaterial>(entity);
if ( material == nullptr) {
shader->setUniformF(shader->uniform("material.ambient"), math::vec3(0.05F, 0.05F, 0.05F));
shader->setUniformF(shader->uniform("material.diffuse"), math::vec3(0.5F, 0.5F, 0.5F));
shader->setUniformF(shader->uniform("material.specular"), math::vec3(0.7F, 0.7F, 0.7F));
shader->setUniformF(shader->uniform("material.shininess"), .078125F);
} else {
shader->setUniformF(shader->uniform("material.ambient"), material->ambient);
shader->setUniformF(shader->uniform("material.diffuse"), material->diffuse);
shader->setUniformF(shader->uniform("material.specular"), material->specular);
shader->setUniformF(shader->uniform("material.shininess"), material->shininess);
}
auto lightPosIdx = shader->uniform("lightPos");
if ( lightPosIdx != -1 ) {
shader->setUniformF(lightPosIdx, lightPos);
......
......@@ -22,6 +22,8 @@
#include <fggl/input/camera_input.h>
#include <fggl/data/heightmap.h>
#include "fggl/gfx/phong.hpp"
namespace fggl::gfx {
//
......@@ -42,6 +44,8 @@ namespace fggl::gfx {
types.make<data::StaticMesh>();
types.make<data::HeightMap>();
types.make<gfx::PhongMaterial>();
// camera dependencies
types.make<fggl::gfx::Camera>();
types.make<fggl::input::FreeCamKeys>();
......
......@@ -66,7 +66,11 @@ namespace fggl::gfx::ogl {
}
inline Location uniform(const std::string_view& name) const {
return glGetUniformLocation( m_obj, name.data() );
auto location = glGetUniformLocation( m_obj, name.data() );
if ( location == -1 ) {
std::cerr << "error: " << name << " does not exist" << std::endl;
}
return location;
}
// primatives
......@@ -82,15 +86,15 @@ namespace fggl::gfx::ogl {
}
// vector versions (float)
inline void setUniformF(Location name, math::vec2f value) {
inline void setUniformF(Location name, const math::vec2f& value) {
glProgramUniform2f(m_obj, name, value.x, value.y);
}
inline void setUniformF(Location name, math::vec3f value) {
inline void setUniformF(Location name, const math::vec3f& value) {
glProgramUniform3f(m_obj, name, value.x, value.y, value.z);
}
inline void setUniformF(Location name, math::vec4f value) {
inline void setUniformF(Location name, const math::vec4f& value) {
glProgramUniform4f(m_obj, name, value.x, value.y, value.z, value.w);
}
......
/*
* ${license.title}
* Copyright (C) 2022 ${license.owner}
* ${license.mailto}
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//
// Created by webpigeon on 05/06/22.
//
#ifndef FGGL_GFX_PHONG_HPP
#define FGGL_GFX_PHONG_HPP
#include "fggl/math/types.hpp"
namespace fggl::gfx {
struct PhongMaterial {
constexpr static const char* name = "gfx::material";
math::vec3 ambient;
math::vec3 diffuse;
math::vec3 specular;
float shininess;
};
} // namesapce fggl::gfx
#endif //FGGL_GFX_PHONG_HPP
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment