Skip to content

Commit

Permalink
Rewrote camera to allow it to be set as a camera.
Browse files Browse the repository at this point in the history
  • Loading branch information
anirul committed Jan 18, 2025
1 parent 91a55a5 commit 8aa6448
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 30 deletions.
8 changes: 4 additions & 4 deletions include/frame/entity_id.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace frame

/**
* @brief The description of what object is on the other side of the entity
* id.
* id.
*/
enum class EntityTypeEnum : std::uint8_t
{
Expand All @@ -24,13 +24,13 @@ enum class EntityTypeEnum : std::uint8_t

/**
* @brief This is used by the code to have an abstraction from pointer to
* structure see data based programming. All object are represented
* by Id that are stored in the level structure.
* structure see data based programming. All object are represented by Id
* that are stored in the level structure.
*/
using EntityId = std::int64_t;
/**
* @brief This is an error in case you have a null id this mean there is
* nothing there or an error.
* nothing there or an error.
*/
constexpr EntityId NullId = 0;

Expand Down
17 changes: 17 additions & 0 deletions include/frame/level.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,22 @@ class Level : public LevelInterface
{
return GetIdFromName(default_camera_name_);
}
/**
* @brief Get the default material id of the shadow material.
* @return An id or an error.
*/
EntityId GetDefaultShadowMaterialId() const override
{
return default_shadow_material_id_;
}
/**
* @brief Set the default material id of the shadow material.
* @param id: Id of the shadow material.
*/
void SetDefaultShadowMaterialId(EntityId id) override
{
default_shadow_material_id_ = id;
}
/**
* @brief Add a mesh and a material id (used for rendering by mesh later
* on).
Expand Down Expand Up @@ -395,6 +411,7 @@ class Level : public LevelInterface
mutable EntityId next_id_maker_ = NullId;
EntityId quad_id_ = 0;
EntityId cube_id_ = 0;
EntityId default_shadow_material_id_ = 0;
std::string name_;
std::string default_texture_name_;
std::string default_root_scene_node_name_;
Expand Down
10 changes: 10 additions & 0 deletions include/frame/level_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,16 @@ class LevelInterface : public NameInterface
* @return An id or an error.
*/
virtual EntityId GetDefaultCameraId() const = 0;
/**
* @brief Get the default material id of the shadow material.
* @return An id or an error.
*/
virtual EntityId GetDefaultShadowMaterialId() const = 0;
/**
* @brief Set the default material id of the shadow material.
* @param id: Id of the shadow material.
*/
virtual void SetDefaultShadowMaterialId(EntityId id) = 0;
/**
* @brief Get the list of children from an id in the node list.
* @param id: The node id you want to get the children.
Expand Down
19 changes: 14 additions & 5 deletions include/frame/light_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
#include "frame/name_interface.h"

namespace frame
{
{

class CameraInterface;

/**
* @brief This has to correspond to proto::SceneLight::LightTypeEnum!
*/
Expand Down Expand Up @@ -42,23 +45,29 @@ struct LightInterface : public NameInterface
* @brief Get the type of the light.
* @return Return the type of the light.
*/
virtual const LightTypeEnum GetType() const = 0;
virtual LightTypeEnum GetType() const = 0;
/**
* @brief Get the type of the shadow.
* @return Return the type of the shadow.
*/
virtual const ShadowTypeEnum GetShadowType() const = 0;
virtual ShadowTypeEnum GetShadowType() const = 0;
/**
* @brief Get the position of the light or the direction in case this is
* a directional light.
* @return Return the position of a light.
*/
virtual const glm::vec3 GetVector() const = 0;
virtual glm::vec3 GetVector() const = 0;
/**
* @brief Get the color intensity.
* @return Return the color of the light.
*/
virtual const glm::vec3 GetColorIntensity() const = 0;
virtual glm::vec3 GetColorIntensity() const = 0;
/**
* @brief Get the shadow view.
* @param camera: Camera use to render the scene.
* @return Return the shadow view.
*/
virtual glm::mat4 ComputeView(const CameraInterface& camera) const = 0;
};

} // End namespace frame.
4 changes: 2 additions & 2 deletions include/frame/plugin_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class UniformInterface;
/**
* @class PluginInterface
* @brief This is the plugin interface that will be used for Stream and
* other plugin.
* other plugin.
*/
class PluginInterface : public NameInterface
{
Expand Down Expand Up @@ -50,7 +50,7 @@ class PluginInterface : public NameInterface
MaterialInterface& material) = 0;
/**
* @brief Called to update variables, called after the main render
* phase.
* phase.
* @param level: The level.
* @return Is the loop continuing?
*/
Expand Down
54 changes: 53 additions & 1 deletion src/frame/opengl/light.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,61 @@
#include "light.h"

#include <stdexcept>
#include <stdexcept>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

namespace frame::opengl
{

glm::mat4 LightPoint::ComputeView(const CameraInterface& camera) const
{
// 1. Use the point light’s world position (assuming GetVector() is
// position).
glm::vec3 lightPos = GetVector();

// 2. Use the camera’s orientation
glm::vec3 front = glm::normalize(camera.GetFront());
glm::vec3 up = glm::normalize(camera.GetUp());

// 3. Build a single view matrix
// We’ll “look” in the camera’s front direction from the light’s
// position. This only makes sense if you want a single direction of
// shadow from the point light. (For a true cubemap, you do 6 passes or
// something else.)
return glm::lookAt(
lightPos, // eye
lightPos + front, // target
up);
}

glm::mat4 LightDirectional::ComputeView(const CameraInterface& camera) const
{
// 1. The light’s direction from your proto (already stored in
// LightDirectional).
// e.g. "GetVector()" returns the directional vector.
glm::vec3 dir = glm::normalize(GetVector());

// 2. Use the camera’s up vector so shadows remain consistent with how the
// camera is oriented.
glm::vec3 up = glm::normalize(camera.GetUp());

// 3. Pick a “center” from the camera’s position (very naive):
// In many engines, we might actually compute a bounding box around what
// the camera sees, then figure out that box’s center.
glm::vec3 center = camera.GetPosition();

// 4. Position the light’s “eye” behind ‘center’ along ‘dir’.
// The distance is somewhat arbitrary or based on your scene size.
float distance = 100.0f; // adjust as needed
glm::vec3 eye = center - dir * distance;

// 5. Build the view matrix
return glm::lookAt(
eye, // “eye” or camera position
center, // “center,” the point the light camera looks at
up // up vector from the real camera
);
}

void LightManager::RegisterToProgram(Program& program) const
{
Expand Down
33 changes: 25 additions & 8 deletions src/frame/opengl/light.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <string>

#include "frame/light_interface.h"
#include "frame/camera_interface.h"
#include "frame/opengl/program.h"

namespace frame::opengl
Expand Down Expand Up @@ -55,15 +56,15 @@ class LightPoint : public LightInterface
* @brief Get the type of the light, coming from the light interface.
* @return Return the type of the light.
*/
const LightTypeEnum GetType() const override
LightTypeEnum GetType() const override
{
return LightTypeEnum::POINT_LIGHT;
}
/**
* @brief Get the type of the shadow, coming from the light interface.
* @return Return the type of the shadow.
*/
const ShadowTypeEnum GetShadowType() const override
ShadowTypeEnum GetShadowType() const override
{
return shadow_type_enum_;
}
Expand All @@ -72,19 +73,27 @@ class LightPoint : public LightInterface
* interface.
* @return Return the position of a light.
*/
const glm::vec3 GetVector() const override
glm::vec3 GetVector() const override
{
return position_;
}
/**
* @brief Get the color intensity, coming from the light interface.
* @return Return the color of the light.
*/
const glm::vec3 GetColorIntensity() const override
glm::vec3 GetColorIntensity() const override
{
return color_intensity_;
}

public:
/**
* @brief Get the shadow view.
* @param camera: Camera use to render the scene.
* @return Return the shadow view.
*/
glm::mat4 ComputeView(const CameraInterface& camera) const;

protected:
glm::vec3 position_;
glm::vec3 color_intensity_;
Expand Down Expand Up @@ -137,15 +146,15 @@ class LightDirectional : public LightInterface
* @brief Get the type of the light, coming from the light interface.
* @return Return the type of the light.
*/
const LightTypeEnum GetType() const override
LightTypeEnum GetType() const override
{
return LightTypeEnum::DIRECTIONAL_LIGHT;
}
/**
* @brief Get the type of the shadow, coming from the light interface.
* @return Return the type of the shadow.
*/
const ShadowTypeEnum GetShadowType() const override
ShadowTypeEnum GetShadowType() const override
{
return shadow_type_enum_;
}
Expand All @@ -154,19 +163,27 @@ class LightDirectional : public LightInterface
* interface.
* @return Return the position of a light.
*/
const glm::vec3 GetVector() const override
glm::vec3 GetVector() const override
{
return direction_;
}
/**
* @brief Get the color intensity, coming from the light interface.
* @return Return the color of the light.
*/
const glm::vec3 GetColorIntensity() const override
glm::vec3 GetColorIntensity() const override
{
return color_intensity_;
}

public:
/**
* @brief Get the shadow view.
* @param camera: Camera use to render the scene.
* @return Return the shadow view.
*/
glm::mat4 ComputeView(const CameraInterface& camera) const;

protected:
glm::vec3 direction_;
glm::vec3 color_intensity_;
Expand Down
64 changes: 54 additions & 10 deletions src/frame/opengl/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,24 +398,68 @@ void Renderer::RenderShadows(const CameraInterface& camera)
// For every light in the level.
for (const auto& light_id : level_.GetLights())
{
EntityId shadow_material_id = level_.GetDefaultShadowMaterialId();
if (shadow_material_id == NullId)
{
throw std::runtime_error("No shadow material id.");
}
// Clear the depth buffer only once per light.
glClear(GL_DEPTH_BUFFER_BIT);
auto& light = level_.GetLightFromId(light_id);
// Check if light has shadow.
if (light.GetShadowType() == ShadowTypeEnum::NO_SHADOW)
{
continue;
}

// For every mesh / material pair in the scene.
for (const auto& p : level_.GetStaticMeshMaterialIds(
proto::SceneStaticMesh::SHADOW_RENDER_TIME))

if (light.GetType() == LightTypeEnum::DIRECTIONAL_LIGHT)
{
auto& mesh = level_.GetStaticMeshFromId(p.first);
auto& material = level_.GetMaterialFromId(p.second);
// Skip transparent object.
if (mesh.GetShadowEffect() ==
// For every mesh / material pair in the scene.
for (const auto& p : level_.GetStaticMeshMaterialIds(
proto::SceneStaticMesh::SHADOW_RENDER_TIME))
{
auto& mesh = level_.GetStaticMeshFromId(p.first);
// Skip object that doesn't cast shadow.
if (mesh.GetShadowEffect() ==
proto::SceneStaticMesh::TRANSPARENT_SHADOW_EFFECT)
{
continue;
{
continue;
}
// Render it acording to the light position.
glm::mat4 proj =
glm::ortho(-50.f, 50.f, -50.f, 50.f, 0.1f, 1000.f);
glm::mat4 view = light.ComputeView(camera);
RenderNode(p.first, shadow_material_id, proj, view);
}
// TODO add the depth map to the light shadow map list.
}
if (light.GetType() == LightTypeEnum::POINT_LIGHT)
{
for (int i = 0; i < 6; ++i)
{
// For every mesh / material pair in the scene.
for (const auto& p : level_.GetStaticMeshMaterialIds(
proto::SceneStaticMesh::SHADOW_RENDER_TIME))
{
auto& mesh = level_.GetStaticMeshFromId(p.first);
// Skip object that doesn't cast shadow.
if (mesh.GetShadowEffect() ==
proto::SceneStaticMesh::TRANSPARENT_SHADOW_EFFECT)
{
continue;
}
// Render it acording to the light position.
// If you want that single “camera-based” pass:
glm::mat4 proj =
glm::perspective(
glm::radians(90.f), 1.f, 0.1f, 1000.f);
glm::mat4 rotation = views_cubemap[i];
glm::mat4 translation =
glm::translate(glm::mat4(1.0f), -light.GetVector());
glm::mat4 view = rotation * translation;
RenderNode(p.first, shadow_material_id, proj, view);
}
// TODO add the depth map to the light shadow map list.
}
}
}
Expand Down

0 comments on commit 8aa6448

Please sign in to comment.