From 9cd1e7c12a93021ff8bec9c852f0d8148720ac70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 27 Dec 2010 19:11:44 +0100 Subject: [PATCH] Scene class and dummy Camera class. --- src/CMakeLists.txt | 2 + src/Camera.cpp | 29 ++++++++++++++ src/Camera.h | 74 ++++++++++++++++++++++++++++++++++ src/Scene.cpp | 66 +++++++++++++++++++++++++++++++ src/Scene.h | 98 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 269 insertions(+) create mode 100644 src/Camera.cpp create mode 100644 src/Camera.h create mode 100644 src/Scene.cpp create mode 100644 src/Scene.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 114c2830f..531eb4b64 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,6 +7,8 @@ add_subdirectory(Math) set(Magnum_SRCS AbstractObject.cpp + Camera.cpp + Scene.cpp ) add_library(Magnum SHARED ${Magnum_SRCS}) diff --git a/src/Camera.cpp b/src/Camera.cpp new file mode 100644 index 000000000..16226ed60 --- /dev/null +++ b/src/Camera.cpp @@ -0,0 +1,29 @@ +/* + Copyright © 2010 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum 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 version 3 for more details. +*/ + +#include "Camera.h" + +namespace Magnum { + +Matrix4 Camera::cameraMatrix() const { + /** @todo How to do that? */ + return Matrix4(); +} + +void Camera::setViewport(int width, int height) { + glViewport(0, 0, width, height); +} + +} diff --git a/src/Camera.h b/src/Camera.h new file mode 100644 index 000000000..476575784 --- /dev/null +++ b/src/Camera.h @@ -0,0 +1,74 @@ +#ifndef Magnum_Camera_h +#define Magnum_Camera_h +/* + Copyright © 2010 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum 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 version 3 for more details. +*/ + +/** @file + * @brief Class Magnum::Camera + */ + +#include "AbstractObject.h" + +namespace Magnum { + +/** + * @brief Camera object + * + * @todo Subclasses - perspective, FBO postprocessing etc. + */ +class Camera: public AbstractObject { + public: + /** @copydoc AbstractObject::AbstractObject() */ + inline Camera(AbstractObject* parent = 0): AbstractObject(parent) {} + + /** + * @brief Camera matrix + * + * Camera matrix describes world position relative to the camera and is + * applied as first. + */ + Matrix4 cameraMatrix() const; + + /** + * @brief Projection matrix + * + * Projection matrix handles e.g. perspective distortion and is applied + * as last. + */ + virtual inline Matrix4 projectionMatrix() const { return Matrix4(); } + + /** + * @brief Set viewport + * @param width Window / buffer width + * @param height Window / buffer height + * + * Called when assigning the camera to the scene or when window + * size changes. Default implementation preserves aspect ratio and + * sets viewport to whole window / buffer size. + */ + virtual void setViewport(int width, int height); + + /** + * @brief Draw camera + * + * Subclasses can draw for example an HUD. Default implementation does + * nothing. + */ + virtual void draw(const Magnum::Matrix4& transformationMatrix, const Magnum::Matrix4& projectionMatrix) {} +}; + +} + +#endif diff --git a/src/Scene.cpp b/src/Scene.cpp new file mode 100644 index 000000000..4b3b4face --- /dev/null +++ b/src/Scene.cpp @@ -0,0 +1,66 @@ +/* + Copyright © 2010 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum 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 version 3 for more details. +*/ + +#include "Scene.h" + +using namespace std; + +namespace Magnum { + +void Scene::setFeature(Scene::Feature feature, bool enabled) { + GLenum _feature; + switch(feature) { + case AlphaBlending: _feature = GL_BLEND; break; + case DepthTest: _feature = GL_DEPTH_TEST; break; + case FaceCulling: _feature = GL_CULL_FACE; break; + default: return; + } + + enabled ? glEnable(_feature) : glDisable(_feature); +} + +void Scene::setClearColor(const Magnum::Vector4& color) { + glClearColor(color.r(), color.g(), color.b(), color.a()); + _clearColor = color; +} + +void Scene::setCamera(Camera* camera) { + camera->setViewport(viewportWidth, viewportHeight); + _camera = camera; +} + +void Scene::draw() { + /* No camera available, nothing to do */ + if(!_camera) return; + + /** @todo Clear only set features */ + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + /* Recursively draw child objects */ + drawChildren(this, _camera->cameraMatrix()); +} + +void Scene::drawChildren(AbstractObject* object, const Matrix4& transformationMatrix) { + for(set::const_iterator it = object->children().begin(); it != object->children().end(); ++it) { + /* Transformation matrix for the object */ + Matrix4 matrix = (*it)->transformation()*transformationMatrix; + + /* Draw the object and its children */ + (*it)->draw(matrix, _camera->projectionMatrix()); + drawChildren(*it, matrix); + } +} + +} diff --git a/src/Scene.h b/src/Scene.h new file mode 100644 index 000000000..e054290b8 --- /dev/null +++ b/src/Scene.h @@ -0,0 +1,98 @@ +#ifndef Magnum_Scene_h +#define Magnum_Scene_h +/* + Copyright © 2010 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum 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 version 3 for more details. +*/ + +/** @file + * @brief Class Magnum::Scene + */ + +#include "Camera.h" + +namespace Magnum { + +/** @brief Scene */ +class Scene: public AbstractObject { + private: + AbstractObject::setTransformation; + AbstractObject::setParent; + + public: + /** @brief Features */ + enum Feature { + AlphaBlending = 0x01, /**< @brief Alpha blending */ + DepthTest = 0x02, /**< @brief Depth test */ + FaceCulling = 0x04 /**< @brief Face culling */ + }; + + /** @brief Constructor */ + inline Scene(): AbstractObject(0), _features(0), _camera(0) { + setClearColor(0.1f, 0.1f, 0.1f, 1.0f); + } + + /** @brief Clear color */ + inline Vector4 clearColor() const { return _clearColor; } + + /** @brief Which features are set */ + inline unsigned int features() const { return _features; } + + /** @brief Camera */ + inline Camera* camera() const { return _camera; } + + /** @brief Set feature */ + void setFeature(Feature feature, bool enabled); + + /** @brief Set clear color */ + void setClearColor(const Vector4& color); + + /** @brief Set clear color */ + inline void setClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) { + setClearColor(Vector4(r, g, b, a)); + } + + /** + * @brief Set viewport size + * + * Just passes the values to active camera. + */ + inline void setViewport(int width, int height) { + if(_camera) _camera->setViewport(width, height); + } + + /** @brief Set camera */ + void setCamera(Camera* camera); + + /** + * @brief Draw whole scene + * + * Recursively draws all child objects. If no camera is available, does + * nothing. + */ + virtual void draw(); + + private: + unsigned int _features; + Vector4 _clearColor; + Camera* _camera; + + unsigned int viewportWidth, viewportHeight; + + inline virtual void draw(const Magnum::Matrix4& transformationMatrix, const Magnum::Matrix4& projectionMatrix) {} + void drawChildren(AbstractObject* object, const Matrix4& transformationMatrix); +}; + +} + +#endif