Patch:[#25163] BGE support for Blender Font objects - unicode support
authorDalai Felinto <dfelinto@gmail.com>
Thu, 16 Dec 2010 10:25:41 +0000 (10:25 +0000)
committerDalai Felinto <dfelinto@gmail.com>
Thu, 16 Dec 2010 10:25:41 +0000 (10:25 +0000)
Problem/Bug:
------------
There were no way to have proper unicode characters (e.g. Japanese) in Blender Game Engine. Now we can :)
You can see a sample here: http://blog.mikepan.com/multi-language-support-in-blender/

Functionality Explanation:
--------------------------
This patch converts the Blender Font Objects to a new BGE type: KX_FontObject
This object inherits KX_GameObject.cpp and has the following properties:
- text (the text of the object)
- size (taken from the Blender object, usually is 1.0)
- resolution (1.0 by default, maybe not really needed, but at least for debugging/the time being it's nice to have)

The way we deal with linked objects is different than Blender. In Blender the text and size are a property of the Text databock. Therefore linked objects necessarily share the same text (and size, although the size of the object datablock affects that too). In BGE they are stored and accessed per object. Without that it would be problematic to have addObject adding texts that don't share the same data.

Known problems/limitations/ToDo:
--------------------------------
1) support for packed font and the <builtin>
2) figure why some fonts are displayed in a different size in 3DView/BGE (BLF)
3) investigate some glitches I see some times
4) support for multiline
5) support for more Blender Font Object options (text aligment, text boxes, ...)

[1] Diego (bdiego) evantually will help on that. For the time being we are using the "default" (ui) font to replace the <builtin>.
[2] but not all of them. I need to cross check who is calculating the size/dpi in/correctly - Blender or BLF. (e.g. fonts that work well - MS Gothic)
[3] I think this may be related to the resolution we are drawing the font
[4] It can't/will not be handled inside BFL. So the way I see it is to implement a mini text library/api that works as a middlelayer between the drawing step and BLF.
    So instead of:
      BLF_draw(fontid, (char *)text, strlen(text));
    We would do:
      MAGIC_ROUTINE_IM_NOT_BLF_draw(fontir, (char *)text, styleflag, width, height);
[5] don't hold your breath ... but if someone wants to have fun in the holidays the (4) and (5) are part of the same problem.

Code Explanation:
-----------------
The patch should be simple to read. They are three may parts:
1) BL_BlenderDataConversion.cpp:: converts the OB_FONT object into a KX_FontObject.cpp and store it in the KX_Scene->m_fonts
2) KetsjiEngine.cpp::RenderFonts:: loop through the texts and call their internal drawing routine.
3) KX_FontObject.cpp::
  a) constructor: load the font of the object, and store other values.
  b) DrawText: calculate the aspect for the given size (sounds hacky but this is how blf works) and call the render routine in RenderTools
4) KX_BlenderGL.cpp (called from rendertools) ::BL_print_game_line:: Draws the text. Using the BLF API

*) In order to handle visibility of the object added with AddObject I'm adding to the m_scene.m_fonts list only the Fonts in a visible layer - unlike Cameras and Lamps where all the objects are added.

Acknowledgements:
----------------
Thanks Benoit for the review and adjustment suggestions.
Thanks Diego for the BFL expertise, patches and support (Latin community ftw)
Thanks my boss for letting me do part of this patch during work time. Good thing we are starting a project in a partnership with a Japanese Foundation and eventual will need unicode in BGE :) for more details on that - www.nereusprogram.org - let's call it the main sponsor of this "bug feature" ;)

22 files changed:
source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
source/gameengine/BlenderRoutines/KX_BlenderGL.h
source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/GamePlayer/common/CMakeLists.txt
source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
source/gameengine/GamePlayer/common/GPC_RenderTools.h
source/gameengine/GamePlayer/common/Makefile
source/gameengine/GamePlayer/common/SConscript
source/gameengine/Ketsji/CMakeLists.txt
source/gameengine/Ketsji/KX_FontObject.cpp [new file with mode: 0755]
source/gameengine/Ketsji/KX_FontObject.h [new file with mode: 0755]
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_KetsjiEngine.cpp
source/gameengine/Ketsji/KX_KetsjiEngine.h
source/gameengine/Ketsji/KX_PythonInitTypes.cpp
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Ketsji/KX_Scene.h
source/gameengine/Ketsji/Makefile
source/gameengine/Ketsji/SConscript
source/gameengine/Rasterizer/RAS_IRenderTools.h

index 2515c1738d7f331e51c826c18d19eac7aa7906e9..ee1e92eee75f0ef78909339fb6ff5eefa45d1258 100644 (file)
@@ -123,6 +123,32 @@ void DisableForText()
        }
 }
 
+/* Print 3D text */
+void BL_print_game_line(int fontid, const char* text, int size, int dpi, float* color, double* mat, float aspect)
+{
+       /* gl prepping */
+       DisableForText();
+
+       /* the actual drawing */
+       glColor4fv(color);
+
+       /* multiply the text matrix by the object matrix */
+       BLF_enable(fontid, BLF_MATRIX|BLF_ASPECT);
+       BLF_matrix(fontid, mat);
+
+       /* aspect is the inverse scale that allows you to increase */
+       /* your resolution without sizing the final text size      */
+       /* the bigger the size, the smaller the aspect             */
+       BLF_aspect(fontid, aspect, aspect, aspect);
+
+       BLF_size(fontid, size, dpi);
+       BLF_position(fontid, 0, 0, 0);
+       BLF_draw(fontid, (char *)text, strlen(text));
+
+       BLF_disable(fontid, BLF_MATRIX|BLF_ASPECT);
+       glEnable(GL_DEPTH_TEST);
+}
+
 void BL_print_gamedebug_line(const char* text, int xco, int yco, int width, int height)
 {      
        /* gl prepping */
index 9c5254dd661d3dcf70d4b32a872193ecd78fd439..6d481470517c62613c23303cc727d16348c8b5b7 100644 (file)
@@ -47,6 +47,7 @@ void  BL_HideMouse(struct wmWindow *win);
 void   BL_NormalMouse(struct wmWindow *win);
 void   BL_WaitMouse(struct wmWindow *win);
 
+void BL_print_game_line(int fontid, const char* text, int size, int dpi, float* color, double* mat, float aspect);
 void BL_print_gamedebug_line(const char* text, int xco, int yco, int width, int height);
 void BL_print_gamedebug_line_padded(const char* text, int xco, int yco, int width, int height);
 
index 3d73655753597a3e70dc4dfe79ba0eb3ab60eb40..bbc2389b875216382c609a4870bdb514ad8e104f 100644 (file)
@@ -275,7 +275,16 @@ void KX_BlenderRenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmat
                }
        }
 }
-
+void KX_BlenderRenderTools::RenderText3D(int fontid,
+                                                                                const char* text,
+                                                                                int size,
+                                                                                int dpi,
+                                                                                float* color,
+                                                                                double* mat,
+                                                                                float aspect)
+{
+       BL_print_game_line(fontid, text, size, dpi, color, mat, aspect);
+}
 
 void KX_BlenderRenderTools::RenderText2D(RAS_TEXT_RENDER_MODE mode,
                                                                                 const char* text,
index 517e0713352006518b2474139a2e7455f83c3728..7d4728f5ef06b407b6c696eb96bdb56657963fef 100644 (file)
@@ -69,7 +69,15 @@ public:
        void                            DisableOpenGLLights();
        void                            ProcessLighting(RAS_IRasterizer *rasty, bool uselights, const MT_Transform& viewmat);
 
-       void                        RenderText2D(RAS_TEXT_RENDER_MODE mode,
+       void                            RenderText3D(int fontid,
+                                                                        const char* text,
+                                                                        int size,
+                                                                        int dpi,
+                                                                        float* color,
+                                                                        double* mat,
+                                                                        float aspect);
+
+       void            RenderText2D(RAS_TEXT_RENDER_MODE mode,
                                                                         const char* text,
                                                                         int xco,
                                                                         int yco,
index 715e5e33e753abb31c4395979d3c398fe096134d..374f5c814d166f46538cdb864280198627303850 100644 (file)
@@ -64,6 +64,7 @@
 #include "KX_Light.h"
 #include "KX_Camera.h"
 #include "KX_EmptyObject.h"
+#include "KX_FontObject.h"
 #include "MT_Point3.h"
 #include "MT_Transform.h"
 #include "MT_MinMax.h"
@@ -1266,10 +1267,13 @@ static void my_get_local_bounds(Object *ob, DerivedMesh *dm, float *center, floa
                        break;
                case OB_CURVE:
                case OB_SURF:
-               case OB_FONT:
                        center[0]= center[1]= center[2]= 0.0;
                        size[0]  = size[1]=size[2]=0.0;
                        break;
+               case OB_FONT:
+                       center[0]= center[1]= center[2]= 0.0;
+                       size[0]  = size[1]=size[2]=1.0;
+                       break;
                case OB_MBALL:
                        bb= ob->bb;
                        break;
@@ -1801,6 +1805,18 @@ static KX_GameObject *gameobject_from_blenderobject(
                // set transformation
                break;
        }
+
+       case OB_FONT:
+       {
+               /* font objects have no bounding box */
+               gameobj = new KX_FontObject(kxscene,KX_Scene::m_callbacks, rendertools, ob);
+
+               /* add to the list only the visible fonts */
+               if((ob->lay & kxscene->GetBlenderScene()->lay) != 0)
+                       kxscene->AddFont(static_cast<KX_FontObject*>(gameobj));
+               break;
+       }
+
        }
        if (gameobj) 
        {
@@ -2703,4 +2719,4 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
        MT_Scalar distance = (activecam)? activecam->GetCameraFar() - activecam->GetCameraNear(): 100.0f;
        RAS_BucketManager *bucketmanager = kxscene->GetBucketManager();
        bucketmanager->OptimizeBuckets(distance);
-}
+}
\ No newline at end of file
index e0338f672e058f290e6686037f527897bb4f2374..43952a15431a9fd33dc1723659771afd501cc4cb 100644 (file)
@@ -37,6 +37,7 @@ set(INC
        ../../../../source/blender/imbuf
        ../../../../source/gameengine/Ketsji
        ../../../../source/blender/blenlib
+       ../../../../source/blender/blenfont
        ../../../../source/blender/blenkernel
        ../../../../source/blender
        ../../../../source/blender/makesdna
index a985decabe4fee1a3db403fcf07466c15d25e729..51cd323a375b2cebc321f00ef96180f1065631d8 100644 (file)
 
 #include "GPC_RenderTools.h"
 
+extern "C" {
+#include "BLF_api.h"
+}
+
 
 unsigned int GPC_RenderTools::m_numgllights;
 
@@ -276,6 +280,35 @@ void GPC_RenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmatrix,in
        }
 }
 
+void GPC_RenderTools::RenderText3D(    int fontid,
+                                                                       const char* text,
+                                                                       int size,
+                                                                       int dpi,
+                                                                       float* color,
+                                                                       double* mat,
+                                                                       float aspect)
+{
+       /* the actual drawing */
+       glColor3fv(color);
+       /* multiply the text matrix by the object matrix */
+       BLF_enable(fontid, BLF_MATRIX|BLF_ASPECT);
+       BLF_matrix(fontid, mat);
+
+       /* aspect is the inverse scale that allows you to increase */
+       /* your resolution without sizing the final text size */
+       /* the bigger the size, the smaller the aspect  */
+       BLF_aspect(fontid, aspect, aspect, aspect);
+
+       BLF_size(fontid, size, dpi);
+       BLF_position(fontid, 0, 0, 0);
+       BLF_draw(fontid, (char *)text, strlen(text));
+
+       BLF_disable(fontid, BLF_MATRIX|BLF_ASPECT);
+       glEnable(GL_DEPTH_TEST);
+}
+
+
 
 void GPC_RenderTools::RenderText2D(RAS_TEXT_RENDER_MODE mode,
                                                                                 const char* text,
index 378c6d8580f96c95f793d5dfb03c4fe781f662d0..714d686439d132107f766549f59e66774384618d 100644 (file)
@@ -68,6 +68,13 @@ public:
        void                            DisableOpenGLLights();
        void                            ProcessLighting(RAS_IRasterizer *rasty, bool uselights, const MT_Transform& viewmat);
 
+       void                            RenderText3D(int fontid,
+                                                                        const char* text,
+                                                                        int size,
+                                                                        int dpi,
+                                                                        float* color,
+                                                                        double* mat,
+                                                                        float aspect);
        /* @attention mode is ignored here */
        void                        RenderText2D(RAS_TEXT_RENDER_MODE mode,
                                                                         const char* text,
index dd6aa9fc98ce50270d289619c6a8b4c2b046942c..39b7a4bd78157051bc82b67f974e5c3cf47d3ed1 100644 (file)
@@ -41,6 +41,7 @@ CPPFLAGS += -I$(OPENGL_HEADERS)
 CPPFLAGS += -I../../../blender/blenkernel
 CPPFLAGS += -I../../../blender/blenloader
 CPPFLAGS += -I../../../blender/blenlib
+CPPFLAGS += -I../../../blender/blenfont
 CPPFLAGS += -I../../../blender/imbuf
 CPPFLAGS += -I../../../blender/makesdna
 CPPFLAGS += -I../../../blender/gpu
index 873f53f25fa7877d80f8ee0470fad38d3742497a..f7a423f4588dafb2babb0d94a6b92fef01f10876 100644 (file)
@@ -26,6 +26,7 @@ incs = ['.',
         '#source/blender/imbuf',
         '#source/gameengine/Ketsji',
         '#source/blender/blenlib',
+        '#source/blender/blenfont',
         '#source/blender/blenkernel',
         '#source/blender',
         '#source/blender/include',
index 4931299a8e5a34c41e35124210b82254c8a0886f..912794d9f757ddb6cbad1710df2ae1a09ba61a81 100644 (file)
@@ -35,6 +35,7 @@ set(INC
        ../../../intern/moto/include
        ../../../source/gameengine/Ketsji 
        ../../../source/blender/blenlib
+       ../../../source/blender/blenfont
        ../../../source/blender/blenkernel
        ../../../source/blender/python
        ../../../source/blender/python/generic
@@ -70,6 +71,7 @@ set(SRC
        KX_ConvertPhysicsObjects.cpp
        KX_Dome.cpp
        KX_EmptyObject.cpp
+       KX_FontObject.cpp
        KX_GameActuator.cpp
        KX_GameObject.cpp
        KX_IPO_SGController.cpp
@@ -135,6 +137,7 @@ set(SRC
        KX_ConvertPhysicsObject.h
        KX_Dome.h
        KX_EmptyObject.h
+       KX_FontObject.h
        KX_GameActuator.h
        KX_GameObject.h
        KX_IInterpolator.h
diff --git a/source/gameengine/Ketsji/KX_FontObject.cpp b/source/gameengine/Ketsji/KX_FontObject.cpp
new file mode 100755 (executable)
index 0000000..2bd41b8
--- /dev/null
@@ -0,0 +1,147 @@
+/**
+ * $Id$
+ *
+ * ***** 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#include "KX_FontObject.h"
+#include "DNA_curve_types.h"
+#include "KX_Scene.h"
+#include "KX_PythonInit.h"
+
+extern "C" {
+#include "BLF_api.h"
+}
+
+#define BGE_FONT_RES 100
+
+KX_FontObject::KX_FontObject(  void* sgReplicationInfo,
+                                                               SG_Callbacks callbacks,
+                                                               RAS_IRenderTools* rendertools,
+                                                               Object *ob):
+       KX_GameObject(sgReplicationInfo, callbacks),
+       m_rendertools(rendertools),
+       m_object(ob),
+       m_dpi(72),
+       m_resolution(1.f),
+       m_color(ob->col) /* initial color - non-animatable */
+{
+       Curve *text = static_cast<Curve *> (ob->data);
+       m_text = text->str;
+       m_fsize = text->fsize;
+
+       /* <builtin> != "default"                                       */
+       /* I hope at some point Blender (2.5x) can have a single font   */
+       /* with unicode support for ui and OB_FONT                      */
+       /* once we have packed working we can load the <builtin> font   */
+       const char* filepath = text->vfont->name;
+       if (strcmp("<builtin>", filepath) == 0)
+               filepath = "default";
+
+       /* XXX - if it's packed it will not work. waiting for bdiego (Diego) fix for that. */
+       m_fontid = BLF_load(filepath);
+       if (m_fontid == -1)
+               m_fontid = BLF_load("default");
+}
+
+KX_FontObject::~KX_FontObject()
+{
+       //remove font from the scene list
+       //it's handled in KX_Scene::NewRemoveObject
+}
+
+CValue* KX_FontObject::GetReplica() {
+       KX_FontObject* replica = new KX_FontObject(*this);
+       replica->ProcessReplica();
+       return replica;
+}
+
+void KX_FontObject::ProcessReplica()
+{
+       KX_GameObject::ProcessReplica();
+       KX_GetActiveScene()->AddFont(this);
+}
+
+void KX_FontObject::DrawText()
+{
+       /* only draws the text if visible */
+       if(this->GetVisible() == 0) return;
+
+       /* XXX 2DO - handle multiple lines
+       /* HARDCODED MULTIPLICATION FACTOR - this will affect the render resolution directly */
+       float RES = BGE_FONT_RES * m_resolution;
+
+       float size = m_fsize * m_object->size[0] * RES;
+       float aspect = 1.f / (m_object->size[0] * RES);
+       m_rendertools->RenderText3D(m_fontid, m_text, int(size), m_dpi, m_color, this->GetOpenGLMatrix(), aspect);
+}
+
+#ifdef WITH_PYTHON
+
+/* ------------------------------------------------------------------------- */
+/* Python Integration Hooks                                                                     */
+/* ------------------------------------------------------------------------- */
+
+PyTypeObject KX_FontObject::Type = {
+       PyVarObject_HEAD_INIT(NULL, 0)
+       "KX_FontObject",
+       sizeof(PyObjectPlus_Proxy),
+       0,
+       py_base_dealloc,
+       0,
+       0,
+       0,
+       0,
+       py_base_repr,
+       0,
+       &KX_GameObject::Sequence,
+       &KX_GameObject::Mapping,
+       0,0,0,
+       NULL,
+       NULL,
+       0,
+       Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+       0,0,0,0,0,0,0,
+       Methods,
+       0,
+       0,
+       &KX_GameObject::Type,
+       0,0,0,0,0,0,
+       py_base_new
+};
+
+PyMethodDef KX_FontObject::Methods[] = {
+       {NULL,NULL} //Sentinel
+};
+
+PyAttributeDef KX_FontObject::Attributes[] = {
+       KX_PYATTRIBUTE_STRING_RW("text", 0, 100, false, KX_FontObject, m_text),
+       KX_PYATTRIBUTE_FLOAT_RW("size", 0.0001f, 10000.0f, KX_FontObject, m_fsize),
+       KX_PYATTRIBUTE_FLOAT_RW("resolution", 0.0001f, 10000.0f, KX_FontObject, m_resolution),
+       /* KX_PYATTRIBUTE_INT_RW("dpi", 0, 10000, false, KX_FontObject, m_dpi), */// no real need for expose this I think
+       { NULL }        //Sentinel
+};
+
+#endif // WITH_PYTHON
diff --git a/source/gameengine/Ketsji/KX_FontObject.h b/source/gameengine/Ketsji/KX_FontObject.h
new file mode 100755 (executable)
index 0000000..21fe1f0
--- /dev/null
@@ -0,0 +1,80 @@
+/**
+ * $Id$
+ *
+ * ***** 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __KX_FONTOBJECT
+#define  __KX_FONTOBJECT
+#include "KX_GameObject.h"
+#include "DNA_vfont_types.h"
+#include "RAS_IRenderTools.h"
+
+class KX_FontObject : public KX_GameObject
+{
+public:
+       Py_Header;
+       KX_FontObject(  void* sgReplicationInfo,
+                                       SG_Callbacks callbacks,
+                                       RAS_IRenderTools* rendertools,
+                                       Object *ob);
+
+       virtual ~KX_FontObject();
+
+       void DrawText();
+
+       /** 
+        * Inherited from CValue -- return a new copy of this
+        * instance allocated on the heap. Ownership of the new 
+        * object belongs with the caller.
+        */
+       virtual CValue* GetReplica();
+       virtual void ProcessReplica();
+
+protected:
+       STR_String              m_text;
+       Object*                 m_object;
+       int                     m_fontid;
+       int                     m_dpi;
+       float                   m_fsize;
+       float                   m_resolution;
+       float*                  m_color;
+
+       class RAS_IRenderTools* m_rendertools;  //needed for drawing routine
+
+/*
+#ifdef WITH_CXX_GUARDEDALLOC
+public:
+       void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:KX_FontObject"); }
+       void operator delete( void *mem ) { MEM_freeN(mem); }
+#endif
+*/
+
+#ifdef WITH_PYTHON
+#endif
+
+};
+
+#endif //__KX_FONTOBJECT
index 7bd7fb8026f66652009791595f8adc09000d688e..f515016d0b998c3ab3aa5e6267266fe2cc986ece 100644 (file)
@@ -47,6 +47,7 @@ typedef unsigned long uint_ptr;
 #include "KX_GameObject.h"
 #include "KX_Camera.h" // only for their ::Type
 #include "KX_Light.h"  // only for their ::Type
+#include "KX_FontObject.h"  // only for their ::Type
 #include "RAS_MeshObject.h"
 #include "KX_MeshProxy.h"
 #include "KX_PolyProxy.h"
@@ -3034,7 +3035,8 @@ bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py
        
        if (    PyObject_TypeCheck(value, &KX_GameObject::Type) ||
                        PyObject_TypeCheck(value, &KX_LightObject::Type)        ||
-                       PyObject_TypeCheck(value, &KX_Camera::Type)     )
+                       PyObject_TypeCheck(value, &KX_Camera::Type)                     ||
+                       PyObject_TypeCheck(value, &KX_FontObject::Type))
        {
                *object = static_cast<KX_GameObject*>BGE_PROXY_REF(value);
                
index 35d02fbc9f4985209340103d6cb9d8552eecd695..f4fd85affb6a7fd6369a59cda20a79d53a81fd31 100644 (file)
@@ -55,6 +55,7 @@
 #include "KX_Scene.h"
 #include "MT_CmMatrix4x4.h"
 #include "KX_Camera.h"
+#include "KX_FontObject.h"
 #include "KX_Dome.h"
 #include "KX_Light.h"
 #include "KX_PythonInit.h"
@@ -1301,10 +1302,26 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
 #endif
 
        scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools);
+
+       //render all the font objects for this scene
+       RenderFonts(scene);
        
        if (scene->GetPhysicsEnvironment())
                scene->GetPhysicsEnvironment()->debugDrawWorld();
 }
+
+void KX_KetsjiEngine::RenderFonts(KX_Scene* scene)
+{
+       list<class KX_FontObject*>* fonts = scene->GetFonts();
+       
+       list<KX_FontObject*>::iterator it = fonts->begin();
+       while(it != fonts->end())
+       {
+               (*it)->DrawText();
+               ++it;
+       }
+}
+
 /*
 To run once per scene
 */
index 4ce14e100cc720a4ee0312863420b6ea691a9a25..8b07a998c3351c65b73e7b89dfb11649c750d809 100644 (file)
@@ -191,6 +191,7 @@ private:
        void                                    RenderShadowBuffers(KX_Scene *scene);
        void                                    SetBackGround(KX_WorldInfo* worldinfo);
        void                                    DoSound(KX_Scene* scene);
+       void                                    RenderFonts(KX_Scene* scene);
 
 public:
        KX_KetsjiEngine(class KX_ISystem* system);
index 3cca4f39f85ba2b6645977beca72969b7a3cd62a..8a9eac216d19ee9c15bdaa37b45370274ff50d3f 100644 (file)
@@ -47,6 +47,7 @@
 #include "KX_ConstraintWrapper.h"
 #include "KX_GameActuator.h"
 #include "KX_Light.h"
+#include "KX_FontObject.h"
 #include "KX_MeshProxy.h"
 #include "KX_MouseFocusSensor.h"
 #include "KX_NetworkMessageActuator.h"
@@ -193,6 +194,7 @@ void initPyTypes(void)
                PyType_Ready_Attr(dict, KX_GameObject, init_getset);
                PyType_Ready_Attr(dict, KX_IpoActuator, init_getset);
                PyType_Ready_Attr(dict, KX_LightObject, init_getset);
+               PyType_Ready_Attr(dict, KX_FontObject, init_getset);
                PyType_Ready_Attr(dict, KX_MeshProxy, init_getset);
                PyType_Ready_Attr(dict, KX_MouseFocusSensor, init_getset);
                PyType_Ready_Attr(dict, KX_NearSensor, init_getset);
index 0605650bb091a5b1f842af1be9cbc57e8ab8c900..1db174d72be7cb32eeef36d717b96d2aa8b2e3a8 100644 (file)
@@ -323,7 +323,10 @@ list<class KX_Camera*>* KX_Scene::GetCameras()
        return &m_cameras;
 }
 
-
+list<class KX_FontObject*>* KX_Scene::GetFonts()
+{
+       return &m_fonts;
+}
 
 void KX_Scene::SetFramingType(RAS_FrameSettings & frame_settings)
 {
@@ -1014,6 +1017,9 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj)
        // in case this is a camera
        m_cameras.remove((KX_Camera*)newobj);
 
+       // in case this is a font
+       m_fonts.remove((KX_FontObject*)newobj);
+
        /* currently does nothing, keep incase we need to Unregister something */
 #if 0
        if (m_sceneConverter)
@@ -1188,6 +1194,27 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj, bool use_gfx, bool u
 #endif
 }
 
+/* Font Object routines */
+void KX_Scene::AddFont(KX_FontObject* font)
+{
+       if (!FindFont(font))
+               m_fonts.push_back(font);
+}
+
+KX_FontObject* KX_Scene::FindFont(KX_FontObject* font)
+{
+       list<KX_FontObject*>::iterator it = m_fonts.begin();
+
+       while ( (it != m_fonts.end()) 
+                       && ((*it) != font) ) {
+         ++it;
+       }
+
+       return ((it == m_fonts.end()) ? NULL : (*it));
+}
+
+
+/* Camera Object routines */
 KX_Camera* KX_Scene::FindCamera(KX_Camera* cam)
 {
        list<KX_Camera*>::iterator it = m_cameras.begin();
index 9b4a6ec5ec6ae96f22c47029c2045c672de2b9ad..6bef3f95dded8744d7395f417feaa7c386af0d5e 100644 (file)
@@ -136,6 +136,13 @@ protected:
         * The set of cameras for this scene
         */
        list<class KX_Camera*>       m_cameras;
+
+       /**
+        * The set of fonts for this scene
+        */
+       list<class KX_FontObject*>       m_fonts;
+
+
        /**
         * Various SCA managers used by the scene
         */
@@ -361,6 +368,27 @@ public:
        GetTimeEventManager(
        );
 
+       /** Font Routines */
+               
+               list<class KX_FontObject*>*
+       GetFonts(
+       );
+
+       /** Find a font in the scene by pointer. */
+               KX_FontObject*              
+       FindFont(
+               KX_FontObject*
+       );
+
+       /** Add a camera to this scene. */
+               void                    
+       AddFont(
+               KX_FontObject*
+       );
+
+
+       /** Camera Routines */
+
                list<class KX_Camera*>*
        GetCameras(
        );
index 79c8626d2956c1f1f2b6716840b90426b685adde..3161351db90dbccfde0a641ec4621b09c4d7af13 100644 (file)
@@ -60,6 +60,7 @@ CPPFLAGS += -I../Converter
 CPPFLAGS += -I../../blender/blenkernel
 CPPFLAGS += -I../../blender/blenlib
 CPPFLAGS += -I../../blender/blenloader
+CPPFLAGS += -I../../blender/blenfont
 CPPFLAGS += -I../../blender/makesdna
 CPPFLAGS += -I../../blender/imbuf
 CPPFLAGS += -I../../blender/gpu
index 3e86080a2f8a3d346d41fac807fb0db2b42f1ca4..56e0db0cc203e1f26971999b49ca85866439e350 100644 (file)
@@ -12,7 +12,7 @@ incs += ' #source/kernel/gen_system #intern/string #intern/guardedalloc'
 incs += ' #source/gameengine/Rasterizer/RAS_OpenGLRasterizer'
 incs += ' #intern/audaspace/intern #source/gameengine/Converter'
 incs += ' #source/gameengine/BlenderRoutines #source/blender/imbuf #intern/moto/include'
-incs += ' #source/gameengine/Ketsji #source/gameengine/Ketsji/KXNetwork #source/blender/blenlib'
+incs += ' #source/gameengine/Ketsji #source/gameengine/Ketsji/KXNetwork #source/blender/blenlib #source/blender/blenfont'
 incs += ' #source/blender/blenkernel #source/blender #source/blender/editors/include'
 incs += ' #source/blender/makesdna #source/blender/python #source/gameengine/Rasterizer'
 incs += ' #source/gameengine/GameLogic #source/gameengine/Expressions #source/gameengine/Network'
index 50de4980e1d354f77fc5c9207a23988e518ea007..dab28de27f4dec138b53083bd17c8667c4f444af 100644 (file)
@@ -98,6 +98,28 @@ public:
                int drawingmode
        )=0;
 
+       /**
+        * Renders 3D text string using BFL.
+        * @param fontid        The id of the font.
+        * @param text          The string to render.
+        * @param size          The size of the text.
+        * @param dpi           The resolution of the text.
+        * @param color         The color of the object.
+        * @param mat           The Matrix of the text object.
+        * @param aspect        A scaling factor to compensate for the size.
+        */
+       virtual 
+               void    
+       RenderText3D(int fontid,
+                                const char* text,
+                                int size,
+                                int dpi,
+                                float* color,
+                                double* mat,
+                                float aspect
+       ) = 0;
+
+
        /**
         * Renders 2D text string.
         * @param mode      The type of text