Ghost Context Refactor
[blender-staging.git] / source / gameengine / VideoTexture / ImageRender.cpp
index 2cc2c6efa1e15b97d0d597a584d4920d730e0533..617e7fd1d8e5bb51a8d04c40249cf2bebf036d29 100644 (file)
@@ -1,24 +1,28 @@
 /*
------------------------------------------------------------------------------
-This source file is part of VideoTexture library
-
-Copyright (c) 2007 The Zdeno Ash Miklas
-
-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 2 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., 59 Temple
-Place - Suite 330, Boston, MA 02111-1307, USA, or go to
-http://www.gnu.org/copyleft/lesser.txt.
------------------------------------------------------------------------------
-*/
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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.
+ *
+ * Copyright (c) 2007 The Zdeno Ash Miklas
+ *
+ * This source file is part of VideoTexture library
+ *
+ * Contributor(s):
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
 
 /** \file gameengine/VideoTexture/ImageRender.cpp
  *  \ingroup bgevideotex
@@ -32,12 +36,13 @@ http://www.gnu.org/copyleft/lesser.txt.
 #include <math.h>
 
 
-#include "GL/glew.h"
+#include "glew-mx.h"
 
 #include "KX_PythonInit.h"
 #include "DNA_scene_types.h"
 #include "RAS_CameraData.h"
 #include "RAS_MeshObject.h"
+#include "RAS_Polygon.h"
 #include "BLI_math.h"
 
 #include "ImageRender.h"
@@ -48,17 +53,17 @@ http://www.gnu.org/copyleft/lesser.txt.
 
 ExceptionID SceneInvalid, CameraInvalid, ObserverInvalid;
 ExceptionID MirrorInvalid, MirrorSizeInvalid, MirrorNormalInvalid, MirrorHorizontal, MirrorTooSmall;
-ExpDesc SceneInvalidDesc (SceneInvalid, "Scene object is invalid");
-ExpDesc CameraInvalidDesc (CameraInvalid, "Camera object is invalid");
-ExpDesc ObserverInvalidDesc (ObserverInvalid, "Observer object is invalid");
-ExpDesc MirrorInvalidDesc (MirrorInvalid, "Mirror object is invalid");
-ExpDesc MirrorSizeInvalidDesc (MirrorSizeInvalid, "Mirror has no vertex or no size");
-ExpDesc MirrorNormalInvalidDesc (MirrorNormalInvalid, "Cannot determine mirror plane");
-ExpDesc MirrorHorizontalDesc (MirrorHorizontal, "Mirror is horizontal in local space");
-ExpDesc MirrorTooSmallDesc (MirrorTooSmall, "Mirror is too small");
+ExpDesc SceneInvalidDesc(SceneInvalid, "Scene object is invalid");
+ExpDesc CameraInvalidDesc(CameraInvalid, "Camera object is invalid");
+ExpDesc ObserverInvalidDesc(ObserverInvalid, "Observer object is invalid");
+ExpDesc MirrorInvalidDesc(MirrorInvalid, "Mirror object is invalid");
+ExpDesc MirrorSizeInvalidDesc(MirrorSizeInvalid, "Mirror has no vertex or no size");
+ExpDesc MirrorNormalInvalidDesc(MirrorNormalInvalid, "Cannot determine mirror plane");
+ExpDesc MirrorHorizontalDesc(MirrorHorizontal, "Mirror is horizontal in local space");
+ExpDesc MirrorTooSmallDesc(MirrorTooSmall, "Mirror is too small");
 
 // constructor
-ImageRender::ImageRender (KX_Scene * scene, KX_Camera * camera) : 
+ImageRender::ImageRender (KX_Scene *scene, KX_Camera * camera) :
     ImageViewport(),
     m_render(true),
     m_scene(scene),
@@ -66,7 +71,9 @@ ImageRender::ImageRender (KX_Scene * scene, KX_Camera * camera) :
     m_owncamera(false),
     m_observer(NULL),
     m_mirror(NULL),
-    m_clip(100.f)
+    m_clip(100.f),
+    m_mirrorHalfWidth(0.f),
+    m_mirrorHalfHeight(0.f)
 {
        // initialize background color
        setBackground(0, 0, 255, 255);
@@ -74,7 +81,6 @@ ImageRender::ImageRender (KX_Scene * scene, KX_Camera * camera) :
        m_engine = KX_GetActiveEngine();
        m_rasterizer = m_engine->GetRasterizer();
        m_canvas = m_engine->GetCanvas();
-       m_rendertools = m_engine->GetRenderTools();
 }
 
 // destructor
@@ -138,7 +144,7 @@ void ImageRender::Render()
                // compute distance of observer to mirror = D - observerPos . normal
                MT_Scalar observerDistance = mirrorPlaneDTerm - observerWorldPos.dot(mirrorWorldZ);
                // if distance < 0.01 => observer is on wrong side of mirror, don't render
-               if (observerDistance < 0.01f)
+               if (observerDistance < 0.01)
                        return;
                // set camera world position = observerPos + normal * 2 * distance
                MT_Point3 cameraWorldPos = observerWorldPos + (MT_Scalar(2.0)*observerDistance)*mirrorWorldZ;
@@ -193,10 +199,9 @@ void ImageRender::Render()
        m_canvas->SetViewPort(m_position[0], m_position[1], m_position[0]+m_capSize[0]-1, m_position[1]+m_capSize[1]-1);
        m_canvas->ClearColor(m_background[0], m_background[1], m_background[2], m_background[3]);
        m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER);
-       m_rasterizer->BeginFrame(RAS_IRasterizer::KX_TEXTURED,m_engine->GetClockTime());
-       m_rendertools->BeginFrame(m_rasterizer);
+       m_rasterizer->BeginFrame(m_engine->GetClockTime());
        m_engine->SetWorldSettings(m_scene->GetWorldInfo());
-       m_rendertools->SetAuxilaryClientInfo(m_scene);
+       m_rasterizer->SetAuxilaryClientInfo(m_scene);
        m_rasterizer->DisplayFog();
        // matrix calculation, don't apply any of the stereo mode
        m_rasterizer->SetStereoMode(RAS_IRasterizer::RAS_STEREO_NOSTEREO);
@@ -208,11 +213,11 @@ void ImageRender::Render()
                            frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar);
 
                m_camera->SetProjectionMatrix(projmat);
-       } else if (m_camera->hasValidProjectionMatrix())
-       {
+       }
+       else if (m_camera->hasValidProjectionMatrix()) {
                m_rasterizer->SetProjectionMatrix(m_camera->GetProjectionMatrix());
-       } else
-       {
+       }
+       else {
                float lens = m_camera->GetLens();
                float sensor_x = m_camera->GetSensorWidth();
                float sensor_y = m_camera->GetSensorHeight();
@@ -241,8 +246,8 @@ void ImageRender::Render()
 
                        projmat = m_rasterizer->GetOrthoMatrix(
                                    frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar);
-               } else
-               {
+               }
+               else {
                        RAS_FramingManager::ComputeDefaultFrustum(
                                    nearfrust,
                                    farfrust,
@@ -269,7 +274,11 @@ void ImageRender::Render()
 
        m_scene->CalculateVisibleMeshes(m_rasterizer,m_camera);
 
-       m_scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools);
+       m_scene->UpdateAnimations(m_engine->GetFrameTime());
+
+       m_scene->RenderBuckets(camtrans, m_rasterizer);
+
+       m_scene->RenderFonts();
 
        // restore the canvas area now that the render is completed
        m_canvas->GetWindowArea() = area;
@@ -277,25 +286,25 @@ void ImageRender::Render()
 
 
 // cast Image pointer to ImageRender
-inline ImageRender * getImageRender (PyImage * self)
+inline ImageRender * getImageRender (PyImage *self)
 { return static_cast<ImageRender*>(self->m_image); }
 
 
 // python methods
 
 // Blender Scene type
-BlendType<KX_Scene> sceneType ("KX_Scene");
+static BlendType<KX_Scene> sceneType ("KX_Scene");
 // Blender Camera type
-BlendType<KX_Camera> cameraType ("KX_Camera");
+static BlendType<KX_Camera> cameraType ("KX_Camera");
 
 
 // object initialization
-static int ImageRender_init (PyObject * pySelf, PyObject * args, PyObject * kwds)
+static int ImageRender_init(PyObject *pySelf, PyObject *args, PyObject *kwds)
 {
        // parameters - scene object
-       PyObject * scene;
+       PyObject *scene;
        // camera object
-       PyObject * camera;
+       PyObject *camera;
        // parameter keywords
        static const char *kwlist[] = {"sceneObj", "cameraObj", NULL};
        // get parameters
@@ -317,7 +326,7 @@ static int ImageRender_init (PyObject * pySelf, PyObject * args, PyObject * kwds
                if (cameraPtr == NULL) THRWEXCP(CameraInvalid, S_OK);
 
                // get pointer to image structure
-               PyImage * self = reinterpret_cast<PyImage*>(pySelf);
+               PyImage *self = reinterpret_cast<PyImage*>(pySelf);
                // create source object
                if (self->m_image != NULL) delete self->m_image;
                self->m_image = new ImageRender(scenePtr, cameraPtr);
@@ -333,7 +342,7 @@ static int ImageRender_init (PyObject * pySelf, PyObject * args, PyObject * kwds
 
 
 // get background color
-PyObject * getBackground (PyImage * self, void * closure)
+static PyObject *getBackground (PyImage *self, void *closure)
 {
        return Py_BuildValue("[BBBB]",
                             getImageRender(self)->getBackground(0),
@@ -343,7 +352,7 @@ PyObject * getBackground (PyImage * self, void * closure)
 }
 
 // set color
-static int setBackground (PyImage * self, PyObject * value, void * closure)
+static int setBackground(PyImage *self, PyObject *value, void *closure)
 {
        // check validity of parameter
        if (value == NULL || !PySequence_Check(value) || PySequence_Size(value) != 4
@@ -356,10 +365,11 @@ static int setBackground (PyImage * self, PyObject * value, void * closure)
                return -1;
        }
        // set background color
-       getImageRender(self)->setBackground((unsigned char)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 0))),
-               (unsigned char)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 1))),
-               (unsigned char)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 2))),
-               (unsigned char)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 3))));
+       getImageRender(self)->setBackground(
+               (unsigned char)(PyLong_AsLong(PySequence_Fast_GET_ITEM(value, 0))),
+               (unsigned char)(PyLong_AsLong(PySequence_Fast_GET_ITEM(value, 1))),
+               (unsigned char)(PyLong_AsLong(PySequence_Fast_GET_ITEM(value, 2))),
+               (unsigned char)(PyLong_AsLong(PySequence_Fast_GET_ITEM(value, 3))));
        // success
        return 0;
 }
@@ -375,7 +385,7 @@ static PyMethodDef imageRenderMethods[] =
 static PyGetSetDef imageRenderGetSets[] =
 { 
        {(char*)"background", (getter)getBackground, (setter)setBackground, (char*)"background color", NULL},
-    // attribute from ImageViewport
+       // attribute from ImageViewport
        {(char*)"capsize", (getter)ImageViewport_getCaptureSize, (setter)ImageViewport_setCaptureSize, (char*)"size of render area", NULL},
        {(char*)"alpha", (getter)ImageViewport_getAlpha, (setter)ImageViewport_setAlpha, (char*)"use alpha in texture", NULL},
        {(char*)"whole", (getter)ImageViewport_getWhole, (setter)ImageViewport_setWhole, (char*)"use whole viewport to render", NULL},
@@ -385,14 +395,15 @@ static PyGetSetDef imageRenderGetSets[] =
        {(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL},
        {(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbor)",  NULL},
        {(char*)"flip", (getter)Image_getFlip, (setter)Image_setFlip, (char*)"flip image vertically", NULL},
+       {(char*)"zbuff", (getter)Image_getZbuff, (setter)Image_setZbuff, (char*)"use depth buffer as texture", NULL},
+       {(char*)"depth", (getter)Image_getDepth, (setter)Image_setDepth, (char*)"get depth information from z-buffer using unsigned int precision", NULL},
        {(char*)"filter", (getter)Image_getFilter, (setter)Image_setFilter, (char*)"pixel filter", NULL},
        {NULL}
 };
 
 
 // define python type
-PyTypeObject ImageRenderType =
-{ 
+PyTypeObject ImageRenderType = {
        PyVarObject_HEAD_INIT(NULL, 0)
        "VideoTexture.ImageRender",   /*tp_name*/
        sizeof(PyImage),          /*tp_basicsize*/
@@ -434,14 +445,14 @@ PyTypeObject ImageRenderType =
 };
 
 // object initialization
-static int ImageMirror_init (PyObject * pySelf, PyObject * args, PyObject * kwds)
+static int ImageMirror_init(PyObject *pySelf, PyObject *args, PyObject *kwds)
 {
        // parameters - scene object
-       PyObject * scene;
+       PyObject *scene;
        // reference object for mirror
-       PyObject * observer;
+       PyObject *observer;
        // object holding the mirror
-       PyObject * mirror;
+       PyObject *mirror;
        // material of the mirror
        short materialID = 0;
        // parameter keywords
@@ -490,7 +501,7 @@ static int ImageMirror_init (PyObject * pySelf, PyObject * args, PyObject * kwds
                        THRWEXCP(MaterialNotAvail, S_OK);
 
                // get pointer to image structure
-               PyImage * self = reinterpret_cast<PyImage*>(pySelf);
+               PyImage *self = reinterpret_cast<PyImage*>(pySelf);
 
                // create source object
                if (self->m_image != NULL)
@@ -510,13 +521,13 @@ static int ImageMirror_init (PyObject * pySelf, PyObject * args, PyObject * kwds
 }
 
 // get background color
-PyObject * getClip (PyImage * self, void * closure)
+static PyObject *getClip (PyImage *self, void *closure)
 {
        return PyFloat_FromDouble(getImageRender(self)->getClip());
 }
 
 // set clip
-static int setClip (PyImage * self, PyObject * value, void * closure)
+static int setClip(PyImage *self, PyObject *value, void *closure)
 {
        // check validity of parameter
        double clip;
@@ -547,13 +558,15 @@ static PyGetSetDef imageMirrorGetSets[] =
        {(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL},
        {(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbor)",  NULL},
        {(char*)"flip", (getter)Image_getFlip, (setter)Image_setFlip, (char*)"flip image vertically", NULL},
+       {(char*)"zbuff", (getter)Image_getZbuff, (setter)Image_setZbuff, (char*)"use depth buffer as texture", NULL},
+       {(char*)"depth", (getter)Image_getDepth, (setter)Image_setDepth, (char*)"get depth information from z-buffer using unsigned int precision", NULL},
        {(char*)"filter", (getter)Image_getFilter, (setter)Image_setFilter, (char*)"pixel filter", NULL},
        {NULL}
 };
 
 
 // constructor
-ImageRender::ImageRender (KX_Scene * scene, KX_GameObject * observer, KX_GameObject * mirror, RAS_IPolyMaterial * mat) :
+ImageRender::ImageRender (KX_Scene *scene, KX_GameObject *observer, KX_GameObject *mirror, RAS_IPolyMaterial *mat) :
     ImageViewport(),
     m_render(false),
     m_scene(scene),
@@ -583,7 +596,6 @@ ImageRender::ImageRender (KX_Scene * scene, KX_GameObject * observer, KX_GameObj
        m_engine = KX_GetActiveEngine();
        m_rasterizer = m_engine->GetRasterizer();
        m_canvas = m_engine->GetCanvas();
-       m_rendertools = m_engine->GetRenderTools();
        // locate the vertex assigned to mat and do following calculation in mesh coordinates
        for (int meshIndex = 0; meshIndex < mirror->GetMeshCount(); meshIndex++)
        {
@@ -604,13 +616,12 @@ ImageRender::ImageRender (KX_Scene * scene, KX_GameObject * observer, KX_GameObj
                                mirrorVerts.push_back(v1);
                                mirrorVerts.push_back(v2);
                                mirrorVerts.push_back(v3);
-                               if (polygon->VertexCount() == 4)
-                               {
+                               if (polygon->VertexCount() == 4) {
                                        v4 = polygon->GetVertex(3);
                                        mirrorVerts.push_back(v4);
                                        area = normal_quad_v3(normal,(float*)v1->getXYZ(), (float*)v2->getXYZ(), (float*)v3->getXYZ(), (float*)v4->getXYZ());
-                               } else
-                               {
+                               }
+                               else {
                                        area = normal_tri_v3(normal,(float*)v1->getXYZ(), (float*)v2->getXYZ(), (float*)v3->getXYZ());
                                }
                                area = fabs(area);
@@ -725,8 +736,7 @@ ImageRender::ImageRender (KX_Scene * scene, KX_GameObject * observer, KX_GameObj
 
 
 // define python type
-PyTypeObject ImageMirrorType =
-{ 
+PyTypeObject ImageMirrorType = {
        PyVarObject_HEAD_INIT(NULL, 0)
        "VideoTexture.ImageMirror",   /*tp_name*/
        sizeof(PyImage),          /*tp_basicsize*/