Explorar el Código

Added FrameBuffer::getCurrent() for retrieving the currently bound FrameBuffer.
Added support for setting a custom projection matrix on Camera class.

sgrenier hace 12 años
padre
commit
e46064b256
Se han modificado 4 ficheros con 74 adiciones y 23 borrados
  1. 41 22
      gameplay/src/Camera.cpp
  2. 21 1
      gameplay/src/Camera.h
  3. 5 0
      gameplay/src/FrameBuffer.cpp
  4. 7 0
      gameplay/src/FrameBuffer.h

+ 41 - 22
gameplay/src/Camera.cpp

@@ -14,18 +14,21 @@
 #define CAMERA_DIRTY_BOUNDS 32
 #define CAMERA_DIRTY_ALL (CAMERA_DIRTY_VIEW | CAMERA_DIRTY_PROJ | CAMERA_DIRTY_VIEW_PROJ | CAMERA_DIRTY_INV_VIEW | CAMERA_DIRTY_INV_VIEW_PROJ | CAMERA_DIRTY_BOUNDS)
 
+// Other misc camera bits
+#define CAMERA_CUSTOM_PROJECTION 64
+
 namespace gameplay
 {
 
 Camera::Camera(float fieldOfView, float aspectRatio, float nearPlane, float farPlane)
     : _type(PERSPECTIVE), _fieldOfView(fieldOfView), _aspectRatio(aspectRatio), _nearPlane(nearPlane), _farPlane(farPlane),
-      _dirtyBits(CAMERA_DIRTY_ALL), _node(NULL)
+      _bits(CAMERA_DIRTY_ALL), _node(NULL)
 {
 }
 
 Camera::Camera(float zoomX, float zoomY, float aspectRatio, float nearPlane, float farPlane)
     : _type(ORTHOGRAPHIC), _aspectRatio(aspectRatio), _nearPlane(nearPlane), _farPlane(farPlane),
-      _dirtyBits(CAMERA_DIRTY_ALL), _node(NULL)
+      _bits(CAMERA_DIRTY_ALL), _node(NULL)
 {
     // Orthographic camera.
     _zoom[0] = zoomX;
@@ -131,7 +134,7 @@ void Camera::setFieldOfView(float fieldOfView)
     GP_ASSERT(_type == Camera::PERSPECTIVE);
 
     _fieldOfView = fieldOfView;
-    _dirtyBits |= CAMERA_DIRTY_PROJ | CAMERA_DIRTY_VIEW_PROJ | CAMERA_DIRTY_INV_VIEW_PROJ | CAMERA_DIRTY_BOUNDS;
+    _bits |= CAMERA_DIRTY_PROJ | CAMERA_DIRTY_VIEW_PROJ | CAMERA_DIRTY_INV_VIEW_PROJ | CAMERA_DIRTY_BOUNDS;
 }
 
 float Camera::getZoomX() const
@@ -146,7 +149,7 @@ void Camera::setZoomX(float zoomX)
     GP_ASSERT(_type == Camera::ORTHOGRAPHIC);
 
     _zoom[0] = zoomX;
-    _dirtyBits |= CAMERA_DIRTY_PROJ | CAMERA_DIRTY_VIEW_PROJ | CAMERA_DIRTY_INV_VIEW_PROJ | CAMERA_DIRTY_BOUNDS;
+    _bits |= CAMERA_DIRTY_PROJ | CAMERA_DIRTY_VIEW_PROJ | CAMERA_DIRTY_INV_VIEW_PROJ | CAMERA_DIRTY_BOUNDS;
 }
 
 float Camera::getZoomY() const
@@ -161,7 +164,7 @@ void Camera::setZoomY(float zoomY)
     GP_ASSERT(_type == Camera::ORTHOGRAPHIC);
 
     _zoom[1] = zoomY;
-    _dirtyBits |= CAMERA_DIRTY_PROJ | CAMERA_DIRTY_VIEW_PROJ | CAMERA_DIRTY_INV_VIEW_PROJ | CAMERA_DIRTY_BOUNDS;
+    _bits |= CAMERA_DIRTY_PROJ | CAMERA_DIRTY_VIEW_PROJ | CAMERA_DIRTY_INV_VIEW_PROJ | CAMERA_DIRTY_BOUNDS;
 }
 
 float Camera::getAspectRatio() const
@@ -172,7 +175,7 @@ float Camera::getAspectRatio() const
 void Camera::setAspectRatio(float aspectRatio)
 {
     _aspectRatio = aspectRatio;
-    _dirtyBits |= CAMERA_DIRTY_PROJ | CAMERA_DIRTY_VIEW_PROJ | CAMERA_DIRTY_INV_VIEW_PROJ | CAMERA_DIRTY_BOUNDS;
+    _bits |= CAMERA_DIRTY_PROJ | CAMERA_DIRTY_VIEW_PROJ | CAMERA_DIRTY_INV_VIEW_PROJ | CAMERA_DIRTY_BOUNDS;
 }
 
 float Camera::getNearPlane() const
@@ -183,7 +186,7 @@ float Camera::getNearPlane() const
 void Camera::setNearPlane(float nearPlane)
 {
     _nearPlane = nearPlane;
-    _dirtyBits |= CAMERA_DIRTY_PROJ | CAMERA_DIRTY_VIEW_PROJ | CAMERA_DIRTY_INV_VIEW_PROJ | CAMERA_DIRTY_BOUNDS;
+    _bits |= CAMERA_DIRTY_PROJ | CAMERA_DIRTY_VIEW_PROJ | CAMERA_DIRTY_INV_VIEW_PROJ | CAMERA_DIRTY_BOUNDS;
 }
 
 float Camera::getFarPlane() const
@@ -194,7 +197,7 @@ float Camera::getFarPlane() const
 void Camera::setFarPlane(float farPlane)
 {
     _farPlane = farPlane;
-    _dirtyBits |= CAMERA_DIRTY_PROJ | CAMERA_DIRTY_VIEW_PROJ | CAMERA_DIRTY_INV_VIEW_PROJ | CAMERA_DIRTY_BOUNDS;
+    _bits |= CAMERA_DIRTY_PROJ | CAMERA_DIRTY_VIEW_PROJ | CAMERA_DIRTY_INV_VIEW_PROJ | CAMERA_DIRTY_BOUNDS;
 }
 
 Node* Camera::getNode() const
@@ -219,13 +222,13 @@ void Camera::setNode(Node* node)
             _node->addListener(this);
         }
 
-        _dirtyBits |= CAMERA_DIRTY_VIEW | CAMERA_DIRTY_VIEW_PROJ | CAMERA_DIRTY_INV_VIEW | CAMERA_DIRTY_INV_VIEW_PROJ | CAMERA_DIRTY_BOUNDS;
+        _bits |= CAMERA_DIRTY_VIEW | CAMERA_DIRTY_VIEW_PROJ | CAMERA_DIRTY_INV_VIEW | CAMERA_DIRTY_INV_VIEW_PROJ | CAMERA_DIRTY_BOUNDS;
     }
 }
 
 const Matrix& Camera::getViewMatrix() const
 {
-    if (_dirtyBits & CAMERA_DIRTY_VIEW)
+    if (_bits & CAMERA_DIRTY_VIEW)
     {
         if (_node)
         {
@@ -237,7 +240,7 @@ const Matrix& Camera::getViewMatrix() const
             _view.setIdentity();
         }
 
-        _dirtyBits &= ~CAMERA_DIRTY_VIEW;
+        _bits &= ~CAMERA_DIRTY_VIEW;
     }
 
     return _view;
@@ -245,11 +248,11 @@ const Matrix& Camera::getViewMatrix() const
 
 const Matrix& Camera::getInverseViewMatrix() const
 {
-    if (_dirtyBits & CAMERA_DIRTY_INV_VIEW)
+    if (_bits & CAMERA_DIRTY_INV_VIEW)
     {
         getViewMatrix().invert(&_inverseView);
 
-        _dirtyBits &= ~CAMERA_DIRTY_INV_VIEW;
+        _bits &= ~CAMERA_DIRTY_INV_VIEW;
     }
 
     return _inverseView;
@@ -257,7 +260,7 @@ const Matrix& Camera::getInverseViewMatrix() const
 
 const Matrix& Camera::getProjectionMatrix() const
 {
-    if (_dirtyBits & CAMERA_DIRTY_PROJ)
+    if (!(_bits & CAMERA_CUSTOM_PROJECTION) && (_bits & CAMERA_DIRTY_PROJ))
     {
         if (_type == PERSPECTIVE)
         {
@@ -268,19 +271,35 @@ const Matrix& Camera::getProjectionMatrix() const
             Matrix::createOrthographic(_zoom[0], _zoom[1], _nearPlane, _farPlane, &_projection);
         }
 
-        _dirtyBits &= ~CAMERA_DIRTY_PROJ;
+        _bits &= ~CAMERA_DIRTY_PROJ;
     }
 
     return _projection;
 }
 
+void Camera::setProjectionMatrix(const Matrix& matrix)
+{
+    _projection = matrix;
+    _bits |= CAMERA_CUSTOM_PROJECTION;
+    _bits |= CAMERA_DIRTY_PROJ | CAMERA_DIRTY_VIEW_PROJ | CAMERA_DIRTY_INV_VIEW_PROJ | CAMERA_DIRTY_BOUNDS;
+}
+
+void Camera::resetProjectionMatrix()
+{
+    if (_bits & CAMERA_CUSTOM_PROJECTION)
+    {
+        _bits &= ~CAMERA_CUSTOM_PROJECTION;
+        _bits |= CAMERA_DIRTY_PROJ | CAMERA_DIRTY_VIEW_PROJ | CAMERA_DIRTY_INV_VIEW_PROJ | CAMERA_DIRTY_BOUNDS;
+    }
+}
+
 const Matrix& Camera::getViewProjectionMatrix() const
 {
-    if (_dirtyBits & CAMERA_DIRTY_VIEW_PROJ)
+    if (_bits & CAMERA_DIRTY_VIEW_PROJ)
     {
         Matrix::multiply(getProjectionMatrix(), getViewMatrix(), &_viewProjection);
 
-        _dirtyBits &= ~CAMERA_DIRTY_VIEW_PROJ;
+        _bits &= ~CAMERA_DIRTY_VIEW_PROJ;
     }
 
     return _viewProjection;
@@ -288,11 +307,11 @@ const Matrix& Camera::getViewProjectionMatrix() const
 
 const Matrix& Camera::getInverseViewProjectionMatrix() const
 {
-    if (_dirtyBits & CAMERA_DIRTY_INV_VIEW_PROJ)
+    if (_bits & CAMERA_DIRTY_INV_VIEW_PROJ)
     {
         getViewProjectionMatrix().invert(&_inverseViewProjection);
 
-        _dirtyBits &= ~CAMERA_DIRTY_INV_VIEW_PROJ;
+        _bits &= ~CAMERA_DIRTY_INV_VIEW_PROJ;
     }
 
     return _inverseViewProjection;
@@ -300,12 +319,12 @@ const Matrix& Camera::getInverseViewProjectionMatrix() const
 
 const Frustum& Camera::getFrustum() const
 {
-    if (_dirtyBits & CAMERA_DIRTY_BOUNDS)
+    if (_bits & CAMERA_DIRTY_BOUNDS)
     {
         // Update our bounding frustum from our view projection matrix.
         _bounds.set(getViewProjectionMatrix());
 
-        _dirtyBits &= ~CAMERA_DIRTY_BOUNDS;
+        _bits &= ~CAMERA_DIRTY_BOUNDS;
     }
 
     return _bounds;
@@ -404,7 +423,7 @@ Camera* Camera::clone(NodeCloneContext &context) const
 
 void Camera::transformChanged(Transform* transform, long cookie)
 {
-    _dirtyBits |= CAMERA_DIRTY_VIEW | CAMERA_DIRTY_INV_VIEW | CAMERA_DIRTY_INV_VIEW_PROJ | CAMERA_DIRTY_VIEW_PROJ | CAMERA_DIRTY_BOUNDS;
+    _bits |= CAMERA_DIRTY_VIEW | CAMERA_DIRTY_INV_VIEW | CAMERA_DIRTY_INV_VIEW_PROJ | CAMERA_DIRTY_VIEW_PROJ | CAMERA_DIRTY_BOUNDS;
 }
 
 }

+ 21 - 1
gameplay/src/Camera.h

@@ -191,6 +191,26 @@ public:
      */
     const Matrix& getProjectionMatrix() const;
 
+    /**
+     * Sets a custom projection matrix to be used by the camera.
+     *
+     * Setting a custom projection matrix results in the internally 
+     * computed projection matrix being completely overriden until
+     * the resetProjectionMatrix method is called. A custom projection
+     * matrix is normally not neccessary, but can be used for special
+     * projection effects, such as setting an oblique view frustum
+     * for near plane clipping.
+     *
+     * @param matrix Custom projection matrix.
+     */
+    void setProjectionMatrix(const Matrix& matrix);
+
+    /**
+     * Resets the camera to use the internally computed projection matrix
+     * instead of any previously specified user-defined matrix.
+     */
+    void resetProjectionMatrix();
+
     /**
      * Gets the camera's view * projection matrix.
      *
@@ -299,7 +319,7 @@ private:
     mutable Matrix _inverseView;
     mutable Matrix _inverseViewProjection;
     mutable Frustum _bounds;
-    mutable int _dirtyBits;
+    mutable int _bits;
     Node* _node;
 };
 

+ 5 - 0
gameplay/src/FrameBuffer.cpp

@@ -276,4 +276,9 @@ FrameBuffer* FrameBuffer::bindDefault()
     return _defaultFrameBuffer;
 }
 
+FrameBuffer* FrameBuffer::getCurrent()
+{
+    return _currentFrameBuffer;
+}
+
 }

+ 7 - 0
gameplay/src/FrameBuffer.h

@@ -157,6 +157,13 @@ public:
      * @ return The default framebuffer.
      */
     static FrameBuffer* bindDefault(); 
+
+    /**
+     * Gets the currently bound FrameBuffer.
+     *
+     * @return The currently bound FrameBuffer.
+     */
+    static FrameBuffer* getCurrent();
      
 private: