diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 976a3ae2b210..1742589a2d91 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1141,9 +1141,7 @@ static KX_GameObject *gameobject_from_blenderobject( /* font objects have no bounding box */ gameobj = new KX_FontObject(kxscene,KX_Scene::m_callbacks, rendertools, ob, do_color_management); - /* add to the list only the visible fonts */ - if ((ob->lay & kxscene->GetBlenderScene()->lay) != 0) - kxscene->AddFont(static_cast(gameobj)); + kxscene->AddFont(static_cast(gameobj)); break; } diff --git a/source/gameengine/Ketsji/CMakeLists.txt b/source/gameengine/Ketsji/CMakeLists.txt index 0422ec8aec67..dfd67f060088 100644 --- a/source/gameengine/Ketsji/CMakeLists.txt +++ b/source/gameengine/Ketsji/CMakeLists.txt @@ -130,6 +130,7 @@ set(SRC KX_SoundActuator.cpp KX_StateActuator.cpp KX_SteeringActuator.cpp + KX_TextMaterial.cpp KX_TimeCategoryLogger.cpp KX_TimeLogger.cpp KX_TouchEventManager.cpp @@ -216,6 +217,7 @@ set(SRC KX_SoundActuator.h KX_StateActuator.h KX_SteeringActuator.h + KX_TextMaterial.h KX_TimeCategoryLogger.h KX_TimeLogger.h KX_TouchEventManager.h diff --git a/source/gameengine/Ketsji/KX_FontObject.cpp b/source/gameengine/Ketsji/KX_FontObject.cpp index 6f3160559bf7..0be76641d391 100644 --- a/source/gameengine/Ketsji/KX_FontObject.cpp +++ b/source/gameengine/Ketsji/KX_FontObject.cpp @@ -35,9 +35,13 @@ #include "KX_Scene.h" #include "KX_Globals.h" #include "KX_PythonInit.h" +#include "KX_TextMaterial.h" #include "BLI_math.h" #include "EXP_StringValue.h" #include "RAS_IRasterizer.h" +#include "RAS_BucketManager.h" +#include "RAS_MaterialBucket.h" +#include "RAS_TextUser.h" /* paths needed for font load */ #include "BLI_blenlib.h" @@ -113,6 +117,85 @@ void KX_FontObject::ProcessReplica() KX_GameObject::ProcessReplica(); } +void KX_FontObject::AddMeshUser() +{ + m_meshUser = new RAS_TextUser(m_pClient_info); + + // set the part of the mesh slot that never change + float *fl = GetOpenGLMatrixPtr()->getPointer(); + m_meshUser->SetMatrix(fl); + + RAS_BucketManager *bucketManager = GetScene()->GetBucketManager(); + bool created = false; + RAS_MaterialBucket *bucket = bucketManager->FindBucket(GetTextMaterial(), created); + + // If the material bucket is just created then we add a new mesh slot. + if (created) { + bucket->AddMesh(NULL); + } + + /* We copy the original mesh slot which is at the begin of the list, if it's not the case it + * doesn't matter as the mesh slot are all similar exepted their mesh user pointer which is + * set to NULL in copy. By copying instead of adding a mesh slot we reuse the same display + * array bucket. + */ + RAS_MeshSlot *ms = bucket->CopyMesh(*bucket->msBegin()); + ms->SetMeshUser(m_meshUser); + ms->SetDeformer(NULL); + m_meshUser->AddMeshSlot(ms); +} + +void KX_FontObject::UpdateBuckets() +{ + // Update datas and add mesh slot to be rendered only if the object is not culled. + if (m_bVisible && m_meshUser) { + if (m_pSGNode->IsDirty()) { + GetOpenGLMatrix(); + } + + // Allow for some logic brick control + if (GetProperty("Text")) { + m_text = split_string(GetProperty("Text")->GetText()); + } + + // update the animated color + GetObjectColor().getValue(m_color); + + // Font Objects don't use the glsl shader, this color management code is copied from gpu_shader_material.glsl + float color[4]; + if (m_do_color_management) { + linearrgb_to_srgb_v4(color, m_color); + } + else { + copy_v4_v4(color, m_color); + } + + // HARDCODED MULTIPLICATION FACTOR - this will affect the render resolution directly + const float RES = BGE_FONT_RES * m_resolution; + + const float size = m_fsize * NodeGetWorldScaling()[0] * RES; + const float aspect = m_fsize / size; + + // Account for offset + MT_Vector3 offset = NodeGetWorldOrientation() * m_offset * NodeGetWorldScaling(); + // Orient the spacing vector + MT_Vector3 spacing = MT_Vector3(0.0f, m_fsize * m_line_spacing, 0.0f); + + RAS_TextUser *textUser = (RAS_TextUser *)m_meshUser; + + textUser->SetColor(MT_Vector4(color)); + textUser->SetFrontFace(!m_bIsNegativeScaling); + textUser->SetFontId(m_fontid); + textUser->SetSize(size); + textUser->SetDpi(m_dpi); + textUser->SetAspect(aspect); + textUser->SetOffset(offset); + textUser->SetSpacing(spacing); + textUser->SetTexts(m_text); + textUser->ActivateMeshSlots(); + } +} + int GetFontId(VFont *vfont) { PackedFile *packedfile = NULL; @@ -158,57 +241,6 @@ int GetFontId(VFont *vfont) return fontid; } -void KX_FontObject::DrawFontText() -{ - // Allow for some logic brick control - if (GetProperty("Text")) - m_text = split_string(GetProperty("Text")->GetText()); - - // only draws the text if visible - if (GetVisible() == 0) { - return; - } - - // update the animated color - GetObjectColor().getValue(m_color); - - // Font Objects don't use the glsl shader, this color management code is copied from gpu_shader_material.glsl - float color[4]; - if (m_do_color_management) { - linearrgb_to_srgb_v4(color, m_color); - } - else { - copy_v4_v4(color, m_color); - } - - // HARDCODED MULTIPLICATION FACTOR - this will affect the render resolution directly - const float RES = BGE_FONT_RES * m_resolution; - - const float size = m_fsize * NodeGetWorldScaling()[0] * RES; - const float aspect = m_fsize / size; - - /* Get a working copy of the OpenGLMatrix to use */ - float *mat = GetOpenGLMatrix(); - - /* Account for offset */ - MT_Vector3 offset = NodeGetWorldOrientation() * m_offset * NodeGetWorldScaling(); - mat[12] += offset[0]; mat[13] += offset[1]; mat[14] += offset[2]; - - /* Orient the spacing vector */ - MT_Vector3 spacing = MT_Vector3(0.0f, m_fsize * m_line_spacing, 0.0f); - spacing = NodeGetWorldOrientation() * spacing * NodeGetWorldScaling()[1]; - - /* Draw each line, taking spacing into consideration */ - for (unsigned int i = 0; i < m_text.size(); ++i) { - if (i != 0) { - mat[12] -= spacing[0]; - mat[13] -= spacing[1]; - mat[14] -= spacing[2]; - } - m_rasterizer->RenderText3D(m_fontid, m_text[i], int(size), m_dpi, color, mat, aspect); - } -} - #ifdef WITH_PYTHON /* ------------------------------------------------------------------------- */ diff --git a/source/gameengine/Ketsji/KX_FontObject.h b/source/gameengine/Ketsji/KX_FontObject.h index 01b4159a9d50..4c1f1c32982e 100644 --- a/source/gameengine/Ketsji/KX_FontObject.h +++ b/source/gameengine/Ketsji/KX_FontObject.h @@ -45,7 +45,8 @@ class KX_FontObject : public KX_GameObject virtual ~KX_FontObject(); - void DrawFontText(); + virtual void AddMeshUser(); + virtual void UpdateBuckets(); /** * Inherited from CValue -- return a new copy of this diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 92e9eb4e778b..8bb2af67c7fb 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -721,7 +721,7 @@ class KX_GameObject : public SCA_IObject * Update buckets to indicate that there is a new * user of this object's meshes. */ - void + virtual void AddMeshUser( ); @@ -730,7 +730,7 @@ class KX_GameObject : public SCA_IObject * creating or duplicating the object, changing * visibility, object color, .. . */ - void UpdateBuckets(); + virtual void UpdateBuckets(); /** * Clear the meshes associated with this class diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index d2e21665132b..da61523f26c8 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -298,8 +298,6 @@ void KX_KetsjiEngine::RenderDome() // do the rendering m_dome->RenderDomeFrame(scene, cam, i); - // render all the font objects for this scene - scene->RenderFonts(); } list *cameras = scene->GetCameras(); @@ -315,8 +313,6 @@ void KX_KetsjiEngine::RenderDome() // do the rendering m_dome->RenderDomeFrame(scene, (*it), i); - // render all the font objects for this scene - scene->RenderFonts(); } it++; @@ -1184,9 +1180,6 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene *scene, KX_Camera *cam) scene->RenderBuckets(camtrans, m_rasterizer); - // render all the font objects for this scene - scene->RenderFonts(); - if (scene->GetPhysicsEnvironment()) scene->GetPhysicsEnvironment()->DebugDrawWorld(); } diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index c7e5cf8a6952..94470bf254c1 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -1749,15 +1749,6 @@ void KX_Scene::RenderBuckets(const MT_Transform & cameratransform, KX_BlenderMaterial::EndFrame(rasty); } -void KX_Scene::RenderFonts() -{ - list::iterator it = m_fonts.begin(); - while (it != m_fonts.end()) { - (*it)->DrawFontText(); - ++it; - } -} - void KX_Scene::UpdateObjectLods() { if (!m_active_camera) diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index 8dbf203b6456..106e95de82e9 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -396,11 +396,6 @@ class KX_Scene : public CValue, public SCA_IScene KX_FontObject* ); - /** Render the fonts in this scene. */ - void - RenderFonts( - ); - /** Camera Routines */ std::list* diff --git a/source/gameengine/Ketsji/KX_TextMaterial.cpp b/source/gameengine/Ketsji/KX_TextMaterial.cpp new file mode 100644 index 000000000000..65740f07f9e4 --- /dev/null +++ b/source/gameengine/Ketsji/KX_TextMaterial.cpp @@ -0,0 +1,116 @@ +/* + * ***** 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. + * + * Contributor(s): Tristan Porteries. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file gameengine/Ketsji/KX_TextMaterial.cpp + * \ingroup ketsji + */ + +#include "KX_TextMaterial.h" + +#include "DNA_material_types.h" + +static KX_TextMaterial textMaterial = KX_TextMaterial(); + +KX_TextMaterial *GetTextMaterial() +{ + return &textMaterial; +} + +KX_TextMaterial::KX_TextMaterial() + :RAS_IPolyMaterial("__TextMaterial__", NULL) +{ + m_rasMode |= (RAS_ALPHA | RAS_TEXT); + m_flag |= RAS_BLENDERGLSL; + m_alphablend = GEMAT_ALPHA; +} + +KX_TextMaterial::~KX_TextMaterial() +{ +} + +void KX_TextMaterial::Activate(RAS_IRasterizer *rasty) +{ +} + +void KX_TextMaterial::Desactivate(RAS_IRasterizer *rasty) +{ +} + +void KX_TextMaterial::ActivateInstancing(RAS_IRasterizer *rasty, void *matrixoffset, void *positionoffset, void *coloroffset, unsigned int stride) +{ +} + +void KX_TextMaterial::DesactivateInstancing() +{ +} + +void KX_TextMaterial::ActivateMeshSlot(RAS_MeshSlot *ms, RAS_IRasterizer *rasty) +{ +} + +const STR_String& KX_TextMaterial::GetTextureName() const +{ + static STR_String empty = ""; + return empty; +} + +Material *KX_TextMaterial::GetBlenderMaterial() const +{ + return NULL; +} + +Image *KX_TextMaterial::GetBlenderImage() const +{ + return NULL; +} + +MTexPoly *KX_TextMaterial::GetMTexPoly() const +{ + return NULL; +} + +Scene *KX_TextMaterial::GetBlenderScene() const +{ + return NULL; +} + +bool KX_TextMaterial::UseInstancing() const +{ + return false; +} + +void KX_TextMaterial::ReleaseMaterial() +{ +} + +void KX_TextMaterial::UpdateIPO(MT_Vector4 rgba, MT_Vector3 specrgb, MT_Scalar hard, MT_Scalar spec, MT_Scalar ref, + MT_Scalar emit, MT_Scalar ambient, MT_Scalar alpha, MT_Scalar specalpha) +{ +} + +void KX_TextMaterial::Replace_IScene(SCA_IScene *val) +{ +} + +void KX_TextMaterial::OnConstruction() +{ +} diff --git a/source/gameengine/Ketsji/KX_TextMaterial.h b/source/gameengine/Ketsji/KX_TextMaterial.h new file mode 100644 index 000000000000..3f10b1e643dc --- /dev/null +++ b/source/gameengine/Ketsji/KX_TextMaterial.h @@ -0,0 +1,64 @@ +/* + * ***** 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. + * + * Contributor(s): Tristan Porteries. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file KX_TextMaterial.h + * \ingroup ketsji + * \brief Fake material used for all text objects. + */ + +#ifndef __KX_TEXTMATERIAL_H__ +#define __KX_TEXTMATERIAL_H__ + +#include "RAS_IPolygonMaterial.h" + +class KX_TextMaterial : public RAS_IPolyMaterial +{ +public: + KX_TextMaterial(); + virtual ~KX_TextMaterial(); + + virtual void Activate(RAS_IRasterizer *rasty); + virtual void Desactivate(RAS_IRasterizer *rasty); + virtual void ActivateInstancing(RAS_IRasterizer *rasty, void *matrixoffset, void *positionoffset, void *coloroffset, unsigned int stride); + virtual void DesactivateInstancing(); + virtual void ActivateMeshSlot(RAS_MeshSlot *ms, RAS_IRasterizer *rasty); + + virtual const STR_String& GetTextureName() const; + virtual Material *GetBlenderMaterial() const; + virtual Image *GetBlenderImage() const; + virtual MTexPoly *GetMTexPoly() const; + virtual Scene *GetBlenderScene() const; + virtual bool UseInstancing() const; + virtual void ReleaseMaterial(); + + virtual void UpdateIPO(MT_Vector4 rgba, MT_Vector3 specrgb, MT_Scalar hard, MT_Scalar spec, MT_Scalar ref, + MT_Scalar emit, MT_Scalar ambient, MT_Scalar alpha, MT_Scalar specalpha); + + virtual void Replace_IScene(SCA_IScene *val); + + virtual void OnConstruction(); +}; + +/// Global text material instance pointer used to create or find a material bucket in the bucket manager. +KX_TextMaterial *GetTextMaterial(); + +#endif // __KX_TEXTMATERIAL_H__ diff --git a/source/gameengine/Rasterizer/CMakeLists.txt b/source/gameengine/Rasterizer/CMakeLists.txt index 552226409185..d10c897a56fe 100644 --- a/source/gameengine/Rasterizer/CMakeLists.txt +++ b/source/gameengine/Rasterizer/CMakeLists.txt @@ -60,6 +60,7 @@ set(SRC RAS_Polygon.cpp RAS_Shader.cpp RAS_Texture.cpp + RAS_TextUser.cpp RAS_TexVert.cpp RAS_ICanvas.cpp RAS_2DFilterData.cpp @@ -91,6 +92,7 @@ set(SRC RAS_Rect.h RAS_Shader.h RAS_Texture.h + RAS_TextUser.h RAS_TexVert.h RAS_OpenGLFilters/RAS_Blur2DFilter.h RAS_OpenGLFilters/RAS_Dilation2DFilter.h diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.cpp b/source/gameengine/Rasterizer/RAS_BucketManager.cpp index 51547984c928..601a9f789623 100644 --- a/source/gameengine/Rasterizer/RAS_BucketManager.cpp +++ b/source/gameengine/Rasterizer/RAS_BucketManager.cpp @@ -332,6 +332,10 @@ RAS_MaterialBucket *RAS_BucketManager::FindBucket(RAS_IPolyMaterial *material, b else m_buckets[useinstancing ? SOLID_SHADOW_INSTANCING_BUCKET : SOLID_SHADOW_BUCKET].push_back(bucket); } + if (material->IsText()) { + m_buckets[TEXT_BUCKET].push_back(bucket); + } + // Used to free the bucket. m_buckets[ALL_BUCKET].push_back(bucket); return bucket; diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.h b/source/gameengine/Rasterizer/RAS_BucketManager.h index 4179d018878f..0cb1ff76c58e 100644 --- a/source/gameengine/Rasterizer/RAS_BucketManager.h +++ b/source/gameengine/Rasterizer/RAS_BucketManager.h @@ -72,6 +72,7 @@ class RAS_BucketManager ALPHA_SHADOW_BUCKET, SOLID_SHADOW_INSTANCING_BUCKET, ALPHA_SHADOW_INSTANCING_BUCKET, + TEXT_BUCKET, ALL_BUCKET, NUM_BUCKET_TYPE, }; diff --git a/source/gameengine/Rasterizer/RAS_DisplayArrayBucket.cpp b/source/gameengine/Rasterizer/RAS_DisplayArrayBucket.cpp index f25d79093745..c481cea9ef90 100644 --- a/source/gameengine/Rasterizer/RAS_DisplayArrayBucket.cpp +++ b/source/gameengine/Rasterizer/RAS_DisplayArrayBucket.cpp @@ -126,6 +126,11 @@ RAS_MaterialBucket *RAS_DisplayArrayBucket::GetMaterialBucket() const return m_bucket; } +RAS_MeshObject *RAS_DisplayArrayBucket::GetMesh() const +{ + return m_mesh; +} + void RAS_DisplayArrayBucket::ActivateMesh(RAS_MeshSlot *slot) { m_activeMeshSlots.push_back(slot); @@ -205,7 +210,7 @@ void RAS_DisplayArrayBucket::UpdateActiveMeshSlots(RAS_IRasterizer *rasty) } } - if (m_mesh->GetModifiedFlag() & RAS_MeshObject::MESH_MODIFIED) { + if (m_mesh && m_mesh->GetModifiedFlag() & RAS_MeshObject::MESH_MODIFIED) { m_meshModified = true; } @@ -217,7 +222,9 @@ void RAS_DisplayArrayBucket::UpdateActiveMeshSlots(RAS_IRasterizer *rasty) void RAS_DisplayArrayBucket::SetMeshUnmodified() { - m_mesh->SetModifiedFlag(0); + if (m_mesh) { + m_mesh->SetModifiedFlag(0); + } } RAS_IStorageInfo *RAS_DisplayArrayBucket::GetStorageInfo() const diff --git a/source/gameengine/Rasterizer/RAS_DisplayArrayBucket.h b/source/gameengine/Rasterizer/RAS_DisplayArrayBucket.h index c1123bff7338..c4a458cb0e0e 100644 --- a/source/gameengine/Rasterizer/RAS_DisplayArrayBucket.h +++ b/source/gameengine/Rasterizer/RAS_DisplayArrayBucket.h @@ -58,7 +58,7 @@ class RAS_DisplayArrayBucket RAS_MaterialBucket *m_bucket; /// The display array = list of vertexes and indexes. RAS_DisplayArray *m_displayArray; - /// The parent mesh object. + /// The parent mesh object, it can be NULL for text objects. RAS_MeshObject *m_mesh; /// The list fo all visible mesh slots to render this frame. RAS_MeshSlotList m_activeMeshSlots; @@ -98,6 +98,7 @@ class RAS_DisplayArrayBucket /// \section Accesor RAS_DisplayArray *GetDisplayArray() const; RAS_MaterialBucket *GetMaterialBucket() const; + RAS_MeshObject *GetMesh() const; /// \section Active Mesh Slots Management. void ActivateMesh(RAS_MeshSlot *slot); diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp index 7164c3548c62..6c33510b3f66 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp @@ -43,7 +43,9 @@ RAS_IPolyMaterial::RAS_IPolyMaterial( m_rasMode(0), m_flag(0) { - m_drawingmode = ConvertFaceMode(game); + if (game) { + m_drawingmode = ConvertFaceMode(game); + } for (unsigned short i = 0; i < RAS_Texture::MaxUnits; ++i) { m_textures[i] = NULL; @@ -82,6 +84,11 @@ bool RAS_IPolyMaterial::IsWire() const return (m_rasMode & RAS_WIRE); } +bool RAS_IPolyMaterial::IsText() const +{ + return (m_rasMode & RAS_TEXT); +} + void RAS_IPolyMaterial::GetRGBAColor(unsigned char *rgba) const { *rgba++ = 0xFF; diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h index 8984d096e844..91340ed75cb0 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h @@ -66,6 +66,7 @@ enum MaterialRasterizerModes RAS_ZSORT = 4, RAS_ALPHA = 8, RAS_WIRE = 64, + RAS_TEXT = 128, RAS_TWOSIDED = 512, }; @@ -107,6 +108,7 @@ class RAS_IPolyMaterial bool IsAlpha() const; bool IsZSort() const; bool IsWire() const; + bool IsText() const; int GetDrawingMode() const; virtual STR_String& GetName(); unsigned int GetFlag() const; diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h index 69c46b5313de..e87882967adf 100644 --- a/source/gameengine/Rasterizer/RAS_IRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h @@ -379,6 +379,9 @@ class RAS_IRasterizer * IndexPrimitives_3DText will render text into the polygons. */ virtual void IndexPrimitives_3DText(class RAS_MeshSlot *ms, class RAS_IPolyMaterial *polymat) = 0; + + /// Render text mesh slot using BLF functions. + virtual void IndexPrimitivesText(RAS_MeshSlot *ms) = 0; virtual void SetProjectionMatrix(MT_CmMatrix4x4 &mat) = 0; diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp index 07b117556e31..141e6665cd40 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp @@ -186,16 +186,19 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa ms->m_mesh->SortPolygons(ms, cameratrans * MT_Transform(meshUser->GetMatrix())); rasty->PushMatrix(); - if (!ms->m_pDeformer || !ms->m_pDeformer->SkipVertexTransform()) { + if ((!ms->m_pDeformer || !ms->m_pDeformer->SkipVertexTransform()) && !m_material->IsText()) { float mat[16]; rasty->GetTransform(meshUser->GetMatrix(), m_material->GetDrawingMode(), mat); rasty->MultMatrix(mat); } if (m_material->GetDrawingMode() & RAS_IRasterizer::RAS_RENDER_3DPOLYGON_TEXT) { - // for text drawing using faces + // for text drawing using faces rasty->IndexPrimitives_3DText(ms, m_material); } + else if (m_material->IsText()) { + rasty->IndexPrimitivesText(ms); + } else { rasty->IndexPrimitives(ms); } @@ -246,13 +249,13 @@ void RAS_MaterialBucket::SetMeshUnmodified() } } -RAS_DisplayArrayBucket *RAS_MaterialBucket::FindDisplayArrayBucket(RAS_DisplayArray *array) +RAS_DisplayArrayBucket *RAS_MaterialBucket::FindDisplayArrayBucket(RAS_DisplayArray *array, RAS_MeshObject *mesh) { for (RAS_DisplayArrayBucketList::iterator it = m_displayArrayBucketList.begin(), end = m_displayArrayBucketList.end(); it != end; ++it) { RAS_DisplayArrayBucket *displayArrayBucket = *it; - if (displayArrayBucket->GetDisplayArray() == array) { + if (displayArrayBucket->GetDisplayArray() == array && displayArrayBucket->GetMesh() == mesh) { return displayArrayBucket; } } diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.h b/source/gameengine/Rasterizer/RAS_MaterialBucket.h index 5d0e8d72244a..e6dcd4394004 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.h +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.h @@ -76,7 +76,7 @@ class RAS_MaterialBucket unsigned int GetNumActiveMeshSlots(); /// Find a display array bucket for the given display array. - RAS_DisplayArrayBucket *FindDisplayArrayBucket(RAS_DisplayArray *array); + RAS_DisplayArrayBucket *FindDisplayArrayBucket(RAS_DisplayArray *array, RAS_MeshObject *mesh); void AddDisplayArrayBucket(RAS_DisplayArrayBucket *bucket); void RemoveDisplayArrayBucket(RAS_DisplayArrayBucket *bucket); diff --git a/source/gameengine/Rasterizer/RAS_MeshSlot.cpp b/source/gameengine/Rasterizer/RAS_MeshSlot.cpp index bce2d3643376..891db3be5642 100644 --- a/source/gameengine/Rasterizer/RAS_MeshSlot.cpp +++ b/source/gameengine/Rasterizer/RAS_MeshSlot.cpp @@ -132,7 +132,7 @@ void RAS_MeshSlot::SetDeformer(RAS_Deformer *deformer) else { // the deformer is not using vertex array (Modifier), release them m_displayArrayBucket->Release(); - m_displayArrayBucket = m_bucket->FindDisplayArrayBucket(NULL); + m_displayArrayBucket = m_bucket->FindDisplayArrayBucket(NULL, m_mesh); if (m_displayArrayBucket) { m_displayArrayBucket->AddRef(); } diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index 5230aa36d4e0..8d54dff4870e 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -42,6 +42,7 @@ #include "RAS_TexVert.h" #include "RAS_MeshObject.h" #include "RAS_MeshUser.h" +#include "RAS_TextUser.h" #include "RAS_Polygon.h" #include "RAS_DisplayArray.h" #include "RAS_ILightObject.h" @@ -873,6 +874,31 @@ bool RAS_OpenGLRasterizer::UseDisplayLists() const return m_storageInfo & RAS_STORAGE_USE_DISPLAY_LIST; } +void RAS_OpenGLRasterizer::IndexPrimitivesText(RAS_MeshSlot *ms) +{ + RAS_TextUser *textUser = (RAS_TextUser *)ms->m_meshUser; + + float mat[16]; + memcpy(mat, textUser->GetMatrix(), sizeof(float) * 16); + + const MT_Vector3& spacing = textUser->GetSpacing(); + const MT_Vector3& offset = textUser->GetOffset(); + + mat[12] += offset[0]; + mat[13] += offset[1]; + mat[14] += offset[2]; + + for (unsigned short int i = 0, size = textUser->GetTexts().size(); i < size; ++i) { + if (i != 0) { + mat[12] -= spacing[0]; + mat[13] -= spacing[1]; + mat[14] -= spacing[2]; + } + RenderText3D(textUser->GetFontId(), textUser->GetTexts()[i], textUser->GetSize(), textUser->GetDpi(), + textUser->GetColor().getValue(), mat, textUser->GetAspect()); + } +} + void RAS_OpenGLRasterizer::IndexPrimitives_3DText(RAS_MeshSlot *ms, class RAS_IPolyMaterial *polymat) { bool obcolor = polymat->UsesObjectColor(); diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h index 604c92fbbf06..1f6f9ff0e031 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h @@ -202,6 +202,7 @@ class RAS_OpenGLRasterizer : public RAS_IRasterizer virtual void IndexPrimitives(class RAS_MeshSlot *ms); virtual void IndexPrimitivesInstancing(RAS_DisplayArrayBucket *arrayBucket); virtual void IndexPrimitives_3DText(class RAS_MeshSlot *ms, class RAS_IPolyMaterial *polymat); + virtual void IndexPrimitivesText(RAS_MeshSlot *ms); virtual void DrawDerivedMesh(class RAS_MeshSlot *ms); virtual void SetProjectionMatrix(MT_CmMatrix4x4 &mat); diff --git a/source/gameengine/Rasterizer/RAS_TextUser.cpp b/source/gameengine/Rasterizer/RAS_TextUser.cpp new file mode 100644 index 000000000000..61875394116d --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_TextUser.cpp @@ -0,0 +1,115 @@ +/* + * ***** 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: all of this file. + * + * Contributor(s): Tristan Porteries. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file RAS_TextUser.cpp + * \ingroup bgerast + */ + +#include "RAS_TextUser.h" +#include "RAS_DisplayArrayBucket.h" + +RAS_TextUser::RAS_TextUser(void *clientobj) + :RAS_MeshUser(clientobj), + m_fontid(0), + m_size(0), + m_dpi(0), + m_aspect(0.0f), + m_offset(MT_Vector3(0.0f, 0.0f, 0.0f)), + m_spacing(MT_Vector3(0.0f, 0.0f, 0.0f)) +{ +} + +RAS_TextUser::~RAS_TextUser() +{ +} + +int RAS_TextUser::GetFontId() const +{ + return m_fontid; +} + +int RAS_TextUser::GetSize() const +{ + return m_size; +} + +int RAS_TextUser::GetDpi() const +{ + return m_dpi; +} + +float RAS_TextUser::GetAspect() const +{ + return m_aspect; +} + +const MT_Vector3& RAS_TextUser::GetOffset() const +{ + return m_offset; +} + +const MT_Vector3& RAS_TextUser::GetSpacing() const +{ + return m_spacing; +} + +const std::vector& RAS_TextUser::GetTexts() const +{ + return m_texts; +} + +void RAS_TextUser::SetFontId(int fontid) +{ + m_fontid = fontid; +} + +void RAS_TextUser::SetSize(int size) +{ + m_size = size; +} + +void RAS_TextUser::SetDpi(int dpi) +{ + m_dpi = dpi; +} + +void RAS_TextUser::SetAspect(float aspect) +{ + m_aspect = aspect; +} + +void RAS_TextUser::SetOffset(const MT_Vector3& offset) +{ + m_offset = offset; +} + +void RAS_TextUser::SetSpacing(const MT_Vector3& spacing) +{ + m_spacing = spacing; +} + +void RAS_TextUser::SetTexts(const std::vector& texts) +{ + m_texts = texts; +} diff --git a/source/gameengine/Rasterizer/RAS_TextUser.h b/source/gameengine/Rasterizer/RAS_TextUser.h new file mode 100644 index 000000000000..b49cb99b8ca9 --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_TextUser.h @@ -0,0 +1,69 @@ +/* + * ***** 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: all of this file. + * + * Contributor(s): Porteries Tristan. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file RAS_TextUser.h + * \ingroup bgerast + */ + +#ifndef __RAS_TEXT_USER_H__ +#define __RAS_TEXT_USER_H__ + +#include "RAS_MeshUser.h" + +#include "STR_String.h" + +class RAS_TextUser : public RAS_MeshUser +{ +private: + std::vector m_texts; + int m_fontid; + int m_size; + int m_dpi; + float m_aspect; + float m_resolution; + MT_Vector3 m_offset; + MT_Vector3 m_spacing; + +public: + RAS_TextUser(void *clientobj); + virtual ~RAS_TextUser(); + + int GetFontId() const; + int GetSize() const; + int GetDpi() const; + float GetAspect() const; + const MT_Vector3& GetOffset() const; + const MT_Vector3& GetSpacing() const; + const std::vector& GetTexts() const; + + void SetFontId(int fontid); + void SetSize(int size); + void SetDpi(int dpi); + void SetAspect(float aspect); + void SetOffset(const MT_Vector3& offset); + void SetSpacing(const MT_Vector3& spacing); + void SetTexts(const std::vector& texts); +}; + +#endif // __RAS_TEXT_USER_H__ diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index 1d246d56e10a..c1c9a9193a4d 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -398,8 +398,6 @@ bool ImageRender::Render() m_scene->RenderBuckets(camtrans, m_rasterizer); - m_scene->RenderFonts(); - // restore the canvas area now that the render is completed m_canvas->GetWindowArea() = area; m_canvas->EndFrame();