diff --git a/demo/data/phong_frag.glsl b/demo/data/phong_frag.glsl index 0d4df5e53b15dd65e1d30162932df4a81e8b5ee2..52157698312f71b36869863c746d76292d1ec377 100644 --- a/demo/data/phong_frag.glsl +++ b/demo/data/phong_frag.glsl @@ -1,8 +1,17 @@ #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); } diff --git a/demo/demo/rollball.cpp b/demo/demo/rollball.cpp index c4fb40076d98a850fd9e4399989dd80755e64bb0..d20e2f3e784ad7ffeb309b5a05895f350b14dbb3 100644 --- a/demo/demo/rollball.cpp +++ b/demo/demo/rollball.cpp @@ -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); diff --git a/fggl/gfx/ogl4/models.cpp b/fggl/gfx/ogl4/models.cpp index f77f3332e73ce26cce66a039c27e2efd8125cc43..db1facd20f19325af4cfdb11779403aece7e7677 100644 --- a/fggl/gfx/ogl4/models.cpp +++ b/fggl/gfx/ogl4/models.cpp @@ -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); diff --git a/include/fggl/gfx/ogl/compat.hpp b/include/fggl/gfx/ogl/compat.hpp index d00abfc778d613da2eb3a2c613e23681bf20e03e..fc50420ee643f21d92695c292479e1e287ca4e0d 100644 --- a/include/fggl/gfx/ogl/compat.hpp +++ b/include/fggl/gfx/ogl/compat.hpp @@ -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>(); diff --git a/include/fggl/gfx/ogl/types.hpp b/include/fggl/gfx/ogl/types.hpp index 4be7b8f07c5b2eff423f7281d42a39259bc587bc..9fec627d3fae55c9d39332a6a61281a19c4900fa 100644 --- a/include/fggl/gfx/ogl/types.hpp +++ b/include/fggl/gfx/ogl/types.hpp @@ -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); } diff --git a/include/fggl/gfx/phong.hpp b/include/fggl/gfx/phong.hpp new file mode 100644 index 0000000000000000000000000000000000000000..2e59714fab9e8f223a2a2de267c690b7afedefbf --- /dev/null +++ b/include/fggl/gfx/phong.hpp @@ -0,0 +1,42 @@ +/* + * ${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