From 0e98380bf45253a74fbd70c421105ce486acf58d Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Tue, 29 May 2012 07:12:12 +0000 Subject: Committing the VBO/Multi-UV patch from Cucumber. I'm putting this here since it still requires a little bit more work before going into trunk (according to Kupoman). However, I'd like to get the major Rasterizer restructuring for storage modes into this branch before people get too crazy with OpenGL refactoring. Also, I'll be making some changes to the converter soon that I hope to use the Multi-UV part of the patch to build from. --- source/gameengine/Rasterizer/RAS_IRasterizer.h | 4 +- .../gameengine/Rasterizer/RAS_MaterialBucket.cpp | 9 +- source/gameengine/Rasterizer/RAS_MeshObject.cpp | 5 +- source/gameengine/Rasterizer/RAS_MeshObject.h | 3 +- .../Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt | 9 +- .../Rasterizer/RAS_OpenGLRasterizer/RAS_IStorage.h | 62 ++++ .../RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp | 38 +- .../RAS_OpenGLRasterizer/RAS_ListRasterizer.h | 6 +- .../RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp | 293 +++------------- .../RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h | 12 +- .../RAS_OpenGLRasterizer/RAS_StorageIM.cpp | 307 ++++++++++++++++ .../RAS_OpenGLRasterizer/RAS_StorageIM.h | 68 ++++ .../RAS_OpenGLRasterizer/RAS_StorageVA.cpp | 315 +++++++++++++++++ .../RAS_OpenGLRasterizer/RAS_StorageVA.h | 77 ++++ .../RAS_OpenGLRasterizer/RAS_StorageVBO.cpp | 272 +++++++++++++++ .../RAS_OpenGLRasterizer/RAS_StorageVBO.h | 102 ++++++ .../RAS_VAOpenGLRasterizer.cpp | 386 --------------------- .../RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h | 73 ---- source/gameengine/Rasterizer/RAS_TexVert.cpp | 26 +- source/gameengine/Rasterizer/RAS_TexVert.h | 26 +- source/gameengine/Rasterizer/RAS_texmatrix.cpp | 6 +- 21 files changed, 1308 insertions(+), 791 deletions(-) create mode 100644 source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_IStorage.h create mode 100644 source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp create mode 100644 source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.h create mode 100644 source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp create mode 100644 source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.h create mode 100644 source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp create mode 100644 source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.h delete mode 100644 source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp delete mode 100644 source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h (limited to 'source/gameengine/Rasterizer') diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h index 828ee01d150..4f053b179a0 100644 --- a/source/gameengine/Rasterizer/RAS_IRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h @@ -52,6 +52,7 @@ using namespace std; class RAS_ICanvas; class RAS_IPolyMaterial; +class RAS_MeshSlot; typedef vector KX_IndexArray; typedef vector KX_VertexArray; @@ -129,7 +130,7 @@ public: RAS_TEXCO_GEN, //< GPU will generate texture coordinates RAS_TEXCO_ORCO, //< Vertex coordinates (object space) RAS_TEXCO_GLOB, //< Vertex coordinates (world space) - RAS_TEXCO_UV1, //< UV coordinates + RAS_TEXCO_UV, //< UV coordinates RAS_TEXCO_OBJECT, //< Use another object's position as coordinates RAS_TEXCO_LAVECTOR, //< Light vector as coordinates RAS_TEXCO_VIEW, //< View vector as coordinates @@ -137,7 +138,6 @@ public: RAS_TEXCO_WINDOW, //< Window coordinates RAS_TEXCO_NORM, //< Normal coordinates RAS_TEXTANGENT, //< - RAS_TEXCO_UV2, //< RAS_TEXCO_VCOL, //< Vertex Color RAS_TEXCO_DISABLE //< Disable this texture unit (cached) }; diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp index a18adfd8986..22572dd8958 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp @@ -47,6 +47,7 @@ #include "RAS_MeshObject.h" #include "RAS_Deformer.h" // __NLA + /* mesh slot */ RAS_MeshSlot::RAS_MeshSlot() : SG_QList() @@ -605,7 +606,8 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa if (ms.m_pDeformer) { - ms.m_pDeformer->Apply(m_material); + if (ms.m_pDeformer->Apply(m_material)); + ms.m_mesh->SetMeshModified(true); // KX_ReInstanceShapeFromMesh(ms.m_mesh); // Recompute the physics mesh. (Can't call KX_* from RAS_) } @@ -648,9 +650,8 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa else rasty->IndexPrimitives(ms); - if (rasty->QueryLists()) - if (ms.m_DisplayList) - ms.m_mesh->SetMeshModified(false); + + ms.m_mesh->SetMeshModified(false); rendertools->PopMatrix(); } diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp index 7da0be3a506..ea8cf9e498c 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp +++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp @@ -324,15 +324,14 @@ void RAS_MeshObject::SetVertexColor(RAS_IPolyMaterial* mat,MT_Vector4 rgba) void RAS_MeshObject::AddVertex(RAS_Polygon *poly, int i, const MT_Point3& xyz, - const MT_Point2& uv, - const MT_Point2& uv2, + const MT_Point2 uvs[RAS_TexVert::MAX_UNIT], const MT_Vector4& tangent, const unsigned int rgba, const MT_Vector3& normal, bool flat, int origindex) { - RAS_TexVert texvert(xyz, uv, uv2, tangent, rgba, normal, flat, origindex); + RAS_TexVert texvert(xyz, uvs, tangent, rgba, normal, flat, origindex); RAS_MeshMaterial *mmat; RAS_DisplayArray *darray; RAS_MeshSlot *slot; diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h index b3e84c4656b..396ed293925 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.h +++ b/source/gameengine/Rasterizer/RAS_MeshObject.h @@ -116,8 +116,7 @@ public: virtual RAS_Polygon* AddPolygon(RAS_MaterialBucket *bucket, int numverts); virtual void AddVertex(RAS_Polygon *poly, int i, const MT_Point3& xyz, - const MT_Point2& uv, - const MT_Point2& uv2, + const MT_Point2 uvs[RAS_TexVert::MAX_UNIT], const MT_Vector4& tangent, const unsigned int rgbacolor, const MT_Vector3& normal, diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt index 189c4f78f77..11cb4b1d9f9 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt @@ -46,12 +46,17 @@ set(SRC RAS_GLExtensionManager.cpp RAS_ListRasterizer.cpp RAS_OpenGLRasterizer.cpp - RAS_VAOpenGLRasterizer.cpp + RAS_StorageIM.cpp + RAS_StorageVA.cpp + RAS_StorageVBO.cpp RAS_GLExtensionManager.h + RAS_IStorage.h RAS_ListRasterizer.h RAS_OpenGLRasterizer.h - RAS_VAOpenGLRasterizer.h + RAS_StorageIM.h + RAS_StorageVA.h + RAS_StorageVBO.h ) add_definitions(-DGLEW_STATIC) diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_IStorage.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_IStorage.h new file mode 100644 index 00000000000..f5c16bc8cd8 --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_IStorage.h @@ -0,0 +1,62 @@ +/* + * ***** 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_STORAGE +#define __KX_STORAGE + +#include "RAS_MaterialBucket.h" + +enum RAS_STORAGE_TYPE { + RAS_AUTO_STORAGE, + RAS_IMMEDIATE, + RAS_VA, + RAS_VBO +}; + +class RAS_IStorage +{ + +public: + virtual ~RAS_IStorage() {}; + + virtual bool Init()=0; + virtual void Exit()=0; + + virtual void IndexPrimitives(RAS_MeshSlot& ms)=0; + virtual void IndexPrimitivesMulti(class RAS_MeshSlot& ms)=0; + + virtual void SetDrawingMode(int drawingmode)=0; + + +#ifdef WITH_CXX_GUARDEDALLOC +public: + void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_IStorage"); } + void operator delete( void *mem ) { MEM_freeN(mem); } +#endif +}; + +#endif //__KX_STORAGE diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp index 1f411a09586..f6246458878 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp @@ -106,9 +106,8 @@ bool RAS_ListSlot::End() -RAS_ListRasterizer::RAS_ListRasterizer(RAS_ICanvas* canvas, bool useVertexArrays, bool lock) -: RAS_VAOpenGLRasterizer(canvas, lock), - mUseVertexArrays(useVertexArrays), +RAS_ListRasterizer::RAS_ListRasterizer(RAS_ICanvas* canvas, bool lock, int storage) +: RAS_OpenGLRasterizer(canvas, storage), mATI(false) { if (!strcmp((const char*)glGetString(GL_VENDOR), "ATI Technologies Inc.")) @@ -238,11 +237,8 @@ void RAS_ListRasterizer::IndexPrimitives(RAS_MeshSlot& ms) return; } } - // derived mesh cannot use vertex array - if (mUseVertexArrays && !ms.m_pDerivedMesh) - RAS_VAOpenGLRasterizer::IndexPrimitives(ms); - else - RAS_OpenGLRasterizer::IndexPrimitives(ms); + + RAS_OpenGLRasterizer::IndexPrimitives(ms); if (ms.m_bDisplayList) { localSlot->EndList(); @@ -267,13 +263,7 @@ void RAS_ListRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms) } } - // workaround: note how we do not use vertex arrays for making display - // lists, since glVertexAttribPointerARB doesn't seem to work correct - // in display lists on ATI? either a bug in the driver or in Blender .. - if (mUseVertexArrays && !mATI && !ms.m_pDerivedMesh) - RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(ms); - else - RAS_OpenGLRasterizer::IndexPrimitivesMulti(ms); + RAS_OpenGLRasterizer::IndexPrimitivesMulti(ms); if (ms.m_bDisplayList) { localSlot->EndList(); @@ -283,29 +273,17 @@ void RAS_ListRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms) bool RAS_ListRasterizer::Init(void) { - if (mUseVertexArrays) { - return RAS_VAOpenGLRasterizer::Init(); - } else { - return RAS_OpenGLRasterizer::Init(); - } + return RAS_OpenGLRasterizer::Init(); } void RAS_ListRasterizer::SetDrawingMode(int drawingmode) { - if (mUseVertexArrays) { - RAS_VAOpenGLRasterizer::SetDrawingMode(drawingmode); - } else { - RAS_OpenGLRasterizer::SetDrawingMode(drawingmode); - } + RAS_OpenGLRasterizer::SetDrawingMode(drawingmode); } void RAS_ListRasterizer::Exit() { - if (mUseVertexArrays) { - RAS_VAOpenGLRasterizer::Exit(); - } else { - RAS_OpenGLRasterizer::Exit(); - } + RAS_OpenGLRasterizer::Exit(); } // eof diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h index 0b36bbf3876..03371896549 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h @@ -7,7 +7,7 @@ #define __RAS_LISTRASTERIZER_H__ #include "RAS_MaterialBucket.h" -#include "RAS_VAOpenGLRasterizer.h" +#include "RAS_OpenGLRasterizer.h" #include #include @@ -49,7 +49,7 @@ typedef std::map RAS_ArrayLists; typedef std::vector RAS_ListSlots; // indexed by material slot number typedef std::map RAS_DerivedMeshLists; -class RAS_ListRasterizer : public RAS_VAOpenGLRasterizer +class RAS_ListRasterizer : public RAS_OpenGLRasterizer { bool mUseVertexArrays; bool mATI; @@ -61,7 +61,7 @@ class RAS_ListRasterizer : public RAS_VAOpenGLRasterizer public: void RemoveListSlot(RAS_ListSlot* list); - RAS_ListRasterizer(RAS_ICanvas* canvas, bool useVertexArrays=false, bool lock=false); + RAS_ListRasterizer(RAS_ICanvas* canvas, bool lock=false, int storage=RAS_AUTO_STORAGE); virtual ~RAS_ListRasterizer(); virtual void IndexPrimitives(class RAS_MeshSlot& ms); diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index 7db433b5b4f..7c0956839a7 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -43,6 +43,10 @@ #include "MT_CmMatrix4x4.h" #include "RAS_IRenderTools.h" // rendering text +#include "RAS_StorageIM.h" +#include "RAS_StorageVA.h" +#include "RAS_StorageVBO.h" + #include "GPU_draw.h" #include "GPU_material.h" #include "GPU_extensions.h" @@ -71,7 +75,7 @@ static GLuint right_eye_vinterlace_mask[32]; */ static GLuint hinterlace_mask[33]; -RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas) +RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas, int storage) :RAS_IRasterizer(canvas), m_2DCanvas(canvas), m_fogenabled(false), @@ -90,7 +94,8 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas) m_attrib_num(0), //m_last_alphablend(GPU_BLEND_SOLID), m_last_frontface(true), - m_materialCachingInfo(0) + m_materialCachingInfo(0), + m_storage_type(storage) { m_viewmatrix.setIdentity(); m_viewinvmatrix.setIdentity(); @@ -104,6 +109,24 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas) hinterlace_mask[32] = 0; m_prevafvalue = GPU_get_anisotropic(); + + if (m_storage_type == RAS_VBO /*|| m_storage_type == RAS_AUTO_STORAGE && GLEW_ARB_vertex_buffer_object*/) + { + m_storage = new RAS_StorageVBO(&m_texco_num, m_texco, &m_attrib_num, m_attrib); + m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib); + m_storage_type = RAS_VBO; + } + else if (m_storage_type == RAS_VA || m_storage_type == RAS_AUTO_STORAGE && GLEW_VERSION_1_1) + { + m_storage = new RAS_StorageVA(&m_texco_num, m_texco, &m_attrib_num, m_attrib); + m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib); + m_storage_type = RAS_VA; + } + else + { + m_storage = m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib); + m_storage_type = RAS_IMMEDIATE; + } } @@ -112,10 +135,12 @@ RAS_OpenGLRasterizer::~RAS_OpenGLRasterizer() { // Restore the previous AF value GPU_set_anisotropic(m_prevafvalue); + delete m_storage; } bool RAS_OpenGLRasterizer::Init() { + bool storage_init; GPU_state_init(); @@ -143,7 +168,9 @@ bool RAS_OpenGLRasterizer::Init() glShadeModel(GL_SMOOTH); - return true; + storage_init = m_storage->Init(); + + return true && storage_init; } @@ -264,6 +291,8 @@ bool RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat) void RAS_OpenGLRasterizer::Exit() { + m_storage->Exit(); + glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glClearDepth(1.0); @@ -286,7 +315,7 @@ void RAS_OpenGLRasterizer::Exit() bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time) { m_time = time; - m_drawingmode = drawingmode; + SetDrawingMode(drawingmode); // Blender camera routine destroys the settings if (m_drawingmode < KX_SOLID) @@ -325,6 +354,8 @@ void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode) if (m_drawingmode == KX_WIREFRAME) glDisable(GL_CULL_FACE); + + m_storage->SetDrawingMode(drawingmode); } int RAS_OpenGLRasterizer::GetDrawingMode() @@ -664,7 +695,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives_3DText(RAS_MeshSlot& ms, glattrib = -1; if (GLEW_ARB_vertex_program) for (unit=0; unitRenderText(polymat->GetDrawingMode(), polymat, @@ -706,256 +737,20 @@ void RAS_OpenGLRasterizer::SetAttrib(TexCoGen coords, int unit) m_attrib[unit] = coords; } -void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv) -{ - int unit; - - if (GLEW_ARB_multitexture) { - for (unit=0; unitIndexPrimitives(ms); + else + m_storage->IndexPrimitives(ms); } void RAS_OpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms) { - IndexPrimitivesInternal(ms, true); -} - -static bool current_wireframe; -static RAS_MaterialBucket *current_bucket; -static RAS_IPolyMaterial *current_polymat; -static RAS_MeshSlot *current_ms; -static RAS_MeshObject *current_mesh; -static int current_blmat_nr; -static GPUVertexAttribs current_gpu_attribs; -static Image *current_image; -static int CheckMaterialDM(int matnr, void *attribs) -{ - // only draw the current material - if (matnr != current_blmat_nr) - return 0; - GPUVertexAttribs *gattribs = (GPUVertexAttribs *)attribs; - if (gattribs) - memcpy(gattribs, ¤t_gpu_attribs, sizeof(GPUVertexAttribs)); - return 1; -} - -/* -static int CheckTexfaceDM(void *mcol, int index) -{ - - // index is the original face index, retrieve the polygon - RAS_Polygon* polygon = (index >= 0 && index < current_mesh->NumPolygons()) ? - current_mesh->GetPolygon(index) : NULL; - if (polygon && polygon->GetMaterial() == current_bucket) { - // must handle color. - if (current_wireframe) - return 2; - if (current_ms->m_bObjectColor) { - MT_Vector4& rgba = current_ms->m_RGBAcolor; - glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); - // don't use mcol - return 2; - } - if (!mcol) { - // we have to set the color from the material - unsigned char rgba[4]; - current_polymat->GetMaterialRGBAColor(rgba); - glColor4ubv((const GLubyte *)rgba); - return 2; - } - return 1; - } - return 0; -} -*/ - -static DMDrawOption CheckTexDM(MTFace *tface, int has_mcol, int matnr) -{ - - // index is the original face index, retrieve the polygon - if (matnr == current_blmat_nr && - (tface == NULL || tface->tpage == current_image)) { - // must handle color. - if (current_wireframe) - return DM_DRAW_OPTION_NO_MCOL; - if (current_ms->m_bObjectColor) { - MT_Vector4& rgba = current_ms->m_RGBAcolor; - glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); - // don't use mcol - return DM_DRAW_OPTION_NO_MCOL; - } - if (!has_mcol) { - // we have to set the color from the material - unsigned char rgba[4]; - current_polymat->GetMaterialRGBAColor(rgba); - glColor4ubv((const GLubyte *)rgba); - return DM_DRAW_OPTION_NO_MCOL; - } - return DM_DRAW_OPTION_NORMAL; - } - return DM_DRAW_OPTION_SKIP; -} - -void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi) -{ - bool obcolor = ms.m_bObjectColor; - bool wireframe = m_drawingmode <= KX_WIREFRAME; - MT_Vector4& rgba = ms.m_RGBAcolor; - RAS_MeshSlot::iterator it; - - if (ms.m_pDerivedMesh) { - // mesh data is in derived mesh, - current_bucket = ms.m_bucket; - current_polymat = current_bucket->GetPolyMaterial(); - current_ms = &ms; - current_mesh = ms.m_mesh; - current_wireframe = wireframe; - // MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL); /* UNUSED */ - - // handle two-side - if (current_polymat->GetDrawingMode() & RAS_IRasterizer::KX_BACKCULL) - this->SetCullFace(true); - else - this->SetCullFace(false); - - if (current_polymat->GetFlag() & RAS_BLENDERGLSL) { - // GetMaterialIndex return the original mface material index, - // increment by 1 to match what derived mesh is doing - current_blmat_nr = current_polymat->GetMaterialIndex()+1; - // For GLSL we need to retrieve the GPU material attribute - Material* blmat = current_polymat->GetBlenderMaterial(); - Scene* blscene = current_polymat->GetBlenderScene(); - if (!wireframe && blscene && blmat) - GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat), ¤t_gpu_attribs); - else - memset(¤t_gpu_attribs, 0, sizeof(current_gpu_attribs)); - // DM draw can mess up blending mode, restore at the end - int current_blend_mode = GPU_get_material_alpha_blend(); - ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM); - GPU_set_material_alpha_blend(current_blend_mode); - } else { - //ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol); - current_blmat_nr = current_polymat->GetMaterialIndex(); - current_image = current_polymat->GetBlenderImage(); - ms.m_pDerivedMesh->drawFacesTex(ms.m_pDerivedMesh, CheckTexDM, NULL, NULL); - } - return; - } - // iterate over display arrays, each containing an index + vertex array - for (ms.begin(it); !ms.end(it); ms.next(it)) { - RAS_TexVert *vertex; - size_t i, j, numvert; - - numvert = it.array->m_type; - - if (it.array->m_type == RAS_DisplayArray::LINE) { - // line drawing - glBegin(GL_LINES); - - for (i=0; igetXYZ()); - - vertex = &it.vertex[it.index[i+1]]; - glVertex3fv(vertex->getXYZ()); - } - - glEnd(); - } - else { - // triangle and quad drawing - if (it.array->m_type == RAS_DisplayArray::TRIANGLE) - glBegin(GL_TRIANGLES); - else - glBegin(GL_QUADS); - - for (i=0; igetRGBA())); - - glNormal3fv(vertex->getNormal()); - - if (multi) - TexCoord(*vertex); - else - glTexCoord2fv(vertex->getUV1()); - } - - glVertex3fv(vertex->getXYZ()); - } - } - - glEnd(); - } - } + if (ms.m_pDerivedMesh) + m_failsafe_storage->IndexPrimitivesMulti(ms); + else + m_storage->IndexPrimitivesMulti(ms); } void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat) diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h index 3b4a6c4900c..bd85367fae8 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h @@ -41,6 +41,7 @@ using namespace std; #include "RAS_IRasterizer.h" +#include "RAS_IStorage.h" #include "RAS_MaterialBucket.h" #include "RAS_ICanvas.h" @@ -83,7 +84,6 @@ class RAS_OpenGLRasterizer : public RAS_IRasterizer float m_ambr; float m_ambg; float m_ambb; - double m_time; MT_Matrix4x4 m_viewmatrix; MT_Matrix4x4 m_viewinvmatrix; @@ -115,9 +115,15 @@ protected: /** Stores the caching information for the last material activated. */ RAS_IPolyMaterial::TCachingInfo m_materialCachingInfo; + /** Making use of a Strategy desing pattern for storage behavior. + Examples of concrete strategies: Vertex Arrays, VBOs, Immediate Mode*/ + int m_storage_type; + RAS_IStorage* m_storage; + RAS_IStorage* m_failsafe_storage; //So derived mesh can use immediate mode + public: double GetTime(); - RAS_OpenGLRasterizer(RAS_ICanvas* canv); + RAS_OpenGLRasterizer(RAS_ICanvas* canv, int storage=RAS_AUTO_STORAGE); virtual ~RAS_OpenGLRasterizer(); /*enum DrawType @@ -166,8 +172,6 @@ public: class RAS_IPolyMaterial* polymat, class RAS_IRenderTools* rendertools); - void IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi); - virtual void SetProjectionMatrix(MT_CmMatrix4x4 & mat); virtual void SetProjectionMatrix(const MT_Matrix4x4 & mat); virtual void SetViewMatrix( diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp new file mode 100644 index 00000000000..dcb10c0dd93 --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp @@ -0,0 +1,307 @@ +/* + * ***** 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 "RAS_StorageIM.h" + +#include "GL/glew.h" +#include "GPU_draw.h" +#include "GPU_extensions.h" +#include "GPU_material.h" + +#include "DNA_meshdata_types.h" + +#include "BKE_DerivedMesh.h" + +RAS_StorageIM::RAS_StorageIM(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib) : + m_texco_num(texco_num), + m_texco(texco), + m_attrib_num(attrib_num), + m_attrib(attrib) +{ +} +RAS_StorageIM::~RAS_StorageIM() +{ +} + +bool RAS_StorageIM::Init() +{ + return true; +} +void RAS_StorageIM::Exit() +{ +} + +void RAS_StorageIM::IndexPrimitives(RAS_MeshSlot& ms) +{ + IndexPrimitivesInternal(ms, false); +} + +void RAS_StorageIM::IndexPrimitivesMulti(class RAS_MeshSlot& ms) +{ + IndexPrimitivesInternal(ms, true); +} + +void RAS_StorageIM::TexCoord(const RAS_TexVert &tv) +{ + int unit; + + if (GLEW_ARB_multitexture) { + for (unit = 0; unit < *m_texco_num; unit++) { + switch(m_texco[unit]) { + case RAS_IRasterizer::RAS_TEXCO_ORCO: + case RAS_IRasterizer::RAS_TEXCO_GLOB: + glMultiTexCoord3fvARB(GL_TEXTURE0_ARB + unit, tv.getXYZ()); + break; + case RAS_IRasterizer::RAS_TEXCO_UV: + glMultiTexCoord2fvARB(GL_TEXTURE0_ARB + unit, tv.getUV(unit)); + break; + case RAS_IRasterizer::RAS_TEXCO_NORM: + glMultiTexCoord3fvARB(GL_TEXTURE0_ARB + unit, tv.getNormal()); + break; + case RAS_IRasterizer::RAS_TEXTANGENT: + glMultiTexCoord4fvARB(GL_TEXTURE0_ARB + unit, tv.getTangent()); + break; + default: + break; + } + } + } + + if (GLEW_ARB_vertex_program) { + int uv = 0; + for (unit = 0; unit < *m_attrib_num; unit++) { + switch(m_attrib[unit]) { + case RAS_IRasterizer::RAS_TEXCO_ORCO: + case RAS_IRasterizer::RAS_TEXCO_GLOB: + glVertexAttrib3fvARB(unit, tv.getXYZ()); + break; + case RAS_IRasterizer::RAS_TEXCO_UV: + glVertexAttrib2fvARB(unit, tv.getUV(uv++)); + break; + case RAS_IRasterizer::RAS_TEXCO_NORM: + glVertexAttrib3fvARB(unit, tv.getNormal()); + break; + case RAS_IRasterizer::RAS_TEXTANGENT: + glVertexAttrib4fvARB(unit, tv.getTangent()); + break; + case RAS_IRasterizer::RAS_TEXCO_VCOL: + glVertexAttrib4ubvARB(unit, tv.getRGBA()); + break; + default: + break; + } + } + } + +} + +void RAS_StorageIM::SetCullFace(bool enable) +{ + if (enable) + glEnable(GL_CULL_FACE); + else + glDisable(GL_CULL_FACE); +} + +static bool current_wireframe; +static RAS_MaterialBucket *current_bucket; +static RAS_IPolyMaterial *current_polymat; +static RAS_MeshSlot *current_ms; +static RAS_MeshObject *current_mesh; +static int current_blmat_nr; +static GPUVertexAttribs current_gpu_attribs; +static Image *current_image; +static int CheckMaterialDM(int matnr, void *attribs) +{ + // only draw the current material + if (matnr != current_blmat_nr) + return 0; + GPUVertexAttribs *gattribs = (GPUVertexAttribs *)attribs; + if (gattribs) + memcpy(gattribs, ¤t_gpu_attribs, sizeof(GPUVertexAttribs)); + return 1; +} + +/* +static int CheckTexfaceDM(void *mcol, int index) +{ + + // index is the original face index, retrieve the polygon + RAS_Polygon* polygon = (index >= 0 && index < current_mesh->NumPolygons()) ? + current_mesh->GetPolygon(index) : NULL; + if (polygon && polygon->GetMaterial() == current_bucket) { + // must handle color. + if (current_wireframe) + return 2; + if (current_ms->m_bObjectColor) { + MT_Vector4& rgba = current_ms->m_RGBAcolor; + glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); + // don't use mcol + return 2; + } + if (!mcol) { + // we have to set the color from the material + unsigned char rgba[4]; + current_polymat->GetMaterialRGBAColor(rgba); + glColor4ubv((const GLubyte *)rgba); + return 2; + } + return 1; + } + return 0; +} +*/ + +static DMDrawOption CheckTexDM(MTFace *tface, int has_mcol, int matnr) +{ + + // index is the original face index, retrieve the polygon + if (matnr == current_blmat_nr && + (tface == NULL || tface->tpage == current_image)) { + // must handle color. + if (current_wireframe) + return DM_DRAW_OPTION_NO_MCOL; + if (current_ms->m_bObjectColor) { + MT_Vector4& rgba = current_ms->m_RGBAcolor; + glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); + // don't use mcol + return DM_DRAW_OPTION_NO_MCOL; + } + if (!has_mcol) { + // we have to set the color from the material + unsigned char rgba[4]; + current_polymat->GetMaterialRGBAColor(rgba); + glColor4ubv((const GLubyte *)rgba); + return DM_DRAW_OPTION_NO_MCOL; + } + return DM_DRAW_OPTION_NORMAL; + } + return DM_DRAW_OPTION_SKIP; +} + +void RAS_StorageIM::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi) +{ + bool obcolor = ms.m_bObjectColor; + bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME; + MT_Vector4& rgba = ms.m_RGBAcolor; + RAS_MeshSlot::iterator it; + + if (ms.m_pDerivedMesh) { + // mesh data is in derived mesh, + current_bucket = ms.m_bucket; + current_polymat = current_bucket->GetPolyMaterial(); + current_ms = &ms; + current_mesh = ms.m_mesh; + current_wireframe = wireframe; + // MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL); /* UNUSED */ + + // handle two-side + if (current_polymat->GetDrawingMode() & RAS_IRasterizer::KX_BACKCULL) + this->SetCullFace(true); + else + this->SetCullFace(false); + + if (current_polymat->GetFlag() & RAS_BLENDERGLSL) { + // GetMaterialIndex return the original mface material index, + // increment by 1 to match what derived mesh is doing + current_blmat_nr = current_polymat->GetMaterialIndex()+1; + // For GLSL we need to retrieve the GPU material attribute + Material* blmat = current_polymat->GetBlenderMaterial(); + Scene* blscene = current_polymat->GetBlenderScene(); + if (!wireframe && blscene && blmat) + GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat), ¤t_gpu_attribs); + else + memset(¤t_gpu_attribs, 0, sizeof(current_gpu_attribs)); + // DM draw can mess up blending mode, restore at the end + int current_blend_mode = GPU_get_material_alpha_blend(); + ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM); + GPU_set_material_alpha_blend(current_blend_mode); + } else { + //ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol); + current_blmat_nr = current_polymat->GetMaterialIndex(); + current_image = current_polymat->GetBlenderImage(); + ms.m_pDerivedMesh->drawFacesTex(ms.m_pDerivedMesh, CheckTexDM, NULL, NULL); + } + return; + } + // iterate over display arrays, each containing an index + vertex array + for (ms.begin(it); !ms.end(it); ms.next(it)) { + RAS_TexVert *vertex; + size_t i, j, numvert; + + numvert = it.array->m_type; + + if (it.array->m_type == RAS_DisplayArray::LINE) { + // line drawing + glBegin(GL_LINES); + + for (i = 0; i < it.totindex; i += 2) + { + vertex = &it.vertex[it.index[i]]; + glVertex3fv(vertex->getXYZ()); + + vertex = &it.vertex[it.index[i+1]]; + glVertex3fv(vertex->getXYZ()); + } + + glEnd(); + } + else { + // triangle and quad drawing + if (it.array->m_type == RAS_DisplayArray::TRIANGLE) + glBegin(GL_TRIANGLES); + else + glBegin(GL_QUADS); + + for (i = 0; i < it.totindex; i += numvert) + { + if (obcolor) + glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); + + for (j = 0; j < numvert; j++) { + vertex = &it.vertex[it.index[i+j]]; + + if (!wireframe) { + if (!obcolor) + glColor4ubv((const GLubyte *)(vertex->getRGBA())); + + glNormal3fv(vertex->getNormal()); + + if (multi) + TexCoord(*vertex); + else + glTexCoord2fv(vertex->getUV(0)); + } + + glVertex3fv(vertex->getXYZ()); + } + } + + glEnd(); + } + } +} diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.h new file mode 100644 index 00000000000..de4ff30d394 --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.h @@ -0,0 +1,68 @@ +/* + * ***** 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_IMMEDIATEMODESTORAGE +#define __KX_IMMEDIATEMODESTORAGE + +#include "RAS_IStorage.h" +#include "RAS_IRasterizer.h" + +class RAS_StorageIM : public RAS_IStorage +{ +public: + RAS_StorageIM(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib); + virtual ~RAS_StorageIM(); + + virtual bool Init(); + virtual void Exit(); + + virtual void IndexPrimitives(RAS_MeshSlot& ms); + virtual void IndexPrimitivesMulti(class RAS_MeshSlot& ms); + + virtual void SetDrawingMode(int drawingmode){m_drawingmode=drawingmode;}; + +protected: + int m_drawingmode; + int* m_texco_num; + int* m_attrib_num; + RAS_IRasterizer::TexCoGen* m_texco; + RAS_IRasterizer::TexCoGen* m_attrib; + + void TexCoord(const RAS_TexVert &tv); + void SetCullFace(bool enable); + + void IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi); + + +#ifdef WITH_CXX_GUARDEDALLOC +public: + void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_StorageIM"); } + void operator delete( void *mem ) { MEM_freeN(mem); } +#endif +}; + +#endif //__KX_IMMEDIATEMODESTORAGE diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp new file mode 100644 index 00000000000..d32932cfeec --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp @@ -0,0 +1,315 @@ +/* + * ***** 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 "RAS_StorageVA.h" + +#include "GL/glew.h" + +RAS_StorageVA::RAS_StorageVA(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib) : + m_texco_num(texco_num), + m_texco(texco), + m_attrib_num(attrib_num), + m_attrib(attrib), + m_last_texco_num(0), + m_last_attrib_num(0) +{ +} + +RAS_StorageVA::~RAS_StorageVA() +{ +} + +bool RAS_StorageVA::Init() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + return true; +} + +void RAS_StorageVA::Exit() +{ +} + +void RAS_StorageVA::IndexPrimitives(RAS_MeshSlot& ms) +{ + static const GLsizei stride = sizeof(RAS_TexVert); + bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME; + RAS_MeshSlot::iterator it; + GLenum drawmode; + + if (!wireframe) + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + + // use glDrawElements to draw each vertexarray + for (ms.begin(it); !ms.end(it); ms.next(it)) { + if (it.totindex == 0) + continue; + + // drawing mode + if (it.array->m_type == RAS_DisplayArray::TRIANGLE) + drawmode = GL_TRIANGLES; + else if (it.array->m_type == RAS_DisplayArray::QUAD) + drawmode = GL_QUADS; + else + drawmode = GL_LINES; + + // colors + if (drawmode != GL_LINES && !wireframe) { + if (ms.m_bObjectColor) { + const MT_Vector4& rgba = ms.m_RGBAcolor; + + glDisableClientState(GL_COLOR_ARRAY); + glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); + } + else { + glColor4f(0.0f, 0.0f, 0.0f, 1.0f); + glEnableClientState(GL_COLOR_ARRAY); + } + } + else + glColor4f(0.0f, 0.0f, 0.0f, 1.0f); + + glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ()); + glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal()); + if (!wireframe) { + glTexCoordPointer(2, GL_FLOAT, stride, it.vertex->getUV(0)); + if (glIsEnabled(GL_COLOR_ARRAY)) + glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA()); + } + + // here the actual drawing takes places + glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index); + } + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + if (!wireframe) { + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + } +} + +void RAS_StorageVA::IndexPrimitivesMulti(class RAS_MeshSlot& ms) +{ + static const GLsizei stride = sizeof(RAS_TexVert); + bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME; + RAS_MeshSlot::iterator it; + GLenum drawmode; + + if (!wireframe) + EnableTextures(true); + + // use glDrawElements to draw each vertexarray + for (ms.begin(it); !ms.end(it); ms.next(it)) { + if (it.totindex == 0) + continue; + + // drawing mode + if (it.array->m_type == RAS_DisplayArray::TRIANGLE) + drawmode = GL_TRIANGLES; + else if (it.array->m_type == RAS_DisplayArray::QUAD) + drawmode = GL_QUADS; + else + drawmode = GL_LINES; + + // colors + if (drawmode != GL_LINES && !wireframe) { + if (ms.m_bObjectColor) { + const MT_Vector4& rgba = ms.m_RGBAcolor; + + glDisableClientState(GL_COLOR_ARRAY); + glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); + } + else { + glColor4f(0.0f, 0.0f, 0.0f, 1.0f); + glEnableClientState(GL_COLOR_ARRAY); + } + } + else + glColor4f(0.0f, 0.0f, 0.0f, 1.0f); + + glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ()); + glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal()); + if (!wireframe) { + TexCoordPtr(it.vertex); + if (glIsEnabled(GL_COLOR_ARRAY)) + glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA()); + } + + // here the actual drawing takes places + glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index); + } + + if (!wireframe) { + glDisableClientState(GL_COLOR_ARRAY); + EnableTextures(false); + } +} + +void RAS_StorageVA::TexCoordPtr(const RAS_TexVert *tv) +{ + /* note: this function must closely match EnableTextures to enable/disable + * the right arrays, otherwise coordinate and attribute pointers from other + * materials can still be used and cause crashes */ + int unit; + + if (GLEW_ARB_multitexture) + { + for (unit = 0; unit < *m_texco_num; unit++) + { + glClientActiveTextureARB(GL_TEXTURE0_ARB+unit); + switch (m_texco[unit]) + { + case RAS_IRasterizer::RAS_TEXCO_ORCO: + case RAS_IRasterizer::RAS_TEXCO_GLOB: + glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getXYZ()); + break; + case RAS_IRasterizer::RAS_TEXCO_UV: + glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV(unit)); + break; + case RAS_IRasterizer::RAS_TEXCO_NORM: + glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getNormal()); + break; + case RAS_IRasterizer::RAS_TEXTANGENT: + glTexCoordPointer(4, GL_FLOAT, sizeof(RAS_TexVert),tv->getTangent()); + break; + default: + break; + } + } + + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } + + if (GLEW_ARB_vertex_program) { + int uv = 0; + for (unit = 0; unit < *m_attrib_num; unit++) { + switch (m_attrib[unit]) { + case RAS_IRasterizer::RAS_TEXCO_ORCO: + case RAS_IRasterizer::RAS_TEXCO_GLOB: + glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getXYZ()); + break; + case RAS_IRasterizer::RAS_TEXCO_UV: + glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV(uv++)); + break; + case RAS_IRasterizer::RAS_TEXCO_NORM: + glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal()); + break; + case RAS_IRasterizer::RAS_TEXTANGENT: + glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent()); + break; + case RAS_IRasterizer::RAS_TEXCO_VCOL: + glVertexAttribPointerARB(unit, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(RAS_TexVert), tv->getRGBA()); + break; + default: + break; + } + } + } +} + +void RAS_StorageVA::EnableTextures(bool enable) +{ + RAS_IRasterizer::TexCoGen *texco, *attrib; + int unit, texco_num, attrib_num; + + /* we cache last texcoords and attribs to ensure we disable the ones that + * were actually last set */ + if (enable) { + texco = m_texco; + texco_num = *m_texco_num; + attrib = m_attrib; + attrib_num = *m_attrib_num; + + memcpy(m_last_texco, m_texco, sizeof(RAS_IRasterizer::TexCoGen)*(*m_texco_num)); + m_last_texco_num = *m_texco_num; + memcpy(m_last_attrib, m_attrib, sizeof(RAS_IRasterizer::TexCoGen)*(*m_attrib_num)); + m_last_attrib_num = *m_attrib_num; + } + else { + texco = m_last_texco; + texco_num = m_last_texco_num; + attrib = m_last_attrib; + attrib_num = m_last_attrib_num; + } + + if (GLEW_ARB_multitexture) { + for (unit = 0; unit < texco_num; unit++) { + glClientActiveTextureARB(GL_TEXTURE0_ARB + unit); + + switch (texco[unit]) + { + case RAS_IRasterizer::RAS_TEXCO_ORCO: + case RAS_IRasterizer::RAS_TEXCO_GLOB: + case RAS_IRasterizer::RAS_TEXCO_UV: + case RAS_IRasterizer::RAS_TEXCO_NORM: + case RAS_IRasterizer::RAS_TEXTANGENT: + if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY); + else glDisableClientState(GL_TEXTURE_COORD_ARRAY); + break; + default: + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + break; + } + } + + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } + else { + if (texco_num) { + if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY); + else glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + } + + if (GLEW_ARB_vertex_program) { + for (unit = 0; unit < attrib_num; unit++) { + switch (attrib[unit]) { + case RAS_IRasterizer::RAS_TEXCO_ORCO: + case RAS_IRasterizer::RAS_TEXCO_GLOB: + case RAS_IRasterizer::RAS_TEXCO_UV: + case RAS_IRasterizer::RAS_TEXCO_NORM: + case RAS_IRasterizer::RAS_TEXTANGENT: + case RAS_IRasterizer::RAS_TEXCO_VCOL: + if (enable) glEnableVertexAttribArrayARB(unit); + else glDisableVertexAttribArrayARB(unit); + break; + default: + glDisableVertexAttribArrayARB(unit); + break; + } + } + } + + if (!enable) { + m_last_texco_num = 0; + m_last_attrib_num = 0; + } +} + diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.h new file mode 100644 index 00000000000..da7766ec5ca --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.h @@ -0,0 +1,77 @@ +/* + * ***** 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_VERTEXARRAYSTORAGE +#define __KX_VERTEXARRAYSTORAGE + +#include "RAS_IStorage.h" +#include "RAS_IRasterizer.h" + +#include "RAS_OpenGLRasterizer.h" + +class RAS_StorageVA : public RAS_IStorage +{ + +public: + RAS_StorageVA(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib); + virtual ~RAS_StorageVA(); + + virtual bool Init(); + virtual void Exit(); + + virtual void IndexPrimitives(RAS_MeshSlot& ms); + virtual void IndexPrimitivesMulti(class RAS_MeshSlot& ms); + + virtual void SetDrawingMode(int drawingmode){m_drawingmode=drawingmode;}; + +protected: + int m_drawingmode; + + int* m_texco_num; + int* m_attrib_num; + + int m_last_texco_num; + int m_last_attrib_num; + + RAS_IRasterizer::TexCoGen* m_texco; + RAS_IRasterizer::TexCoGen* m_attrib; + + RAS_IRasterizer::TexCoGen m_last_texco[RAS_MAX_TEXCO]; + RAS_IRasterizer::TexCoGen m_last_attrib[RAS_MAX_ATTRIB]; + + virtual void EnableTextures(bool enable); + virtual void TexCoordPtr(const RAS_TexVert *tv); + + +#ifdef WITH_CXX_GUARDEDALLOC +public: + void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_StorageVA"); } + void operator delete( void *mem ) { MEM_freeN(mem); } +#endif +}; + +#endif //__KX_VERTEXARRAYSTORAGE diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp new file mode 100644 index 00000000000..e38dc367eff --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp @@ -0,0 +1,272 @@ +/* + * ***** 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 "RAS_StorageVBO.h" +#include "RAS_MeshObject.h" + +#include "GL/glew.h" + +VBO::VBO(RAS_DisplayArray *data, unsigned int indices) +{ + this->data = data; + this->size = data->m_vertex.size(); + this->indices = indices; + this->stride = 28*sizeof(GLfloat); + + // Determine drawmode + if (data->m_type == data->QUAD) + this->mode = GL_QUADS; + else if (data->m_type == data->TRIANGLE) + this->mode = GL_TRIANGLES; + else + this->mode = GL_LINE; + + // Generate Buffers + glGenBuffersARB(1, &this->ibo); + glGenBuffersARB(1, &this->vbo_id); + + // Allocate some space to gather data into before uploading to GPU + this->vbo = new GLfloat[this->stride*this->size]; + + // Fill the buffers with initial data + UpdateIndices(); + UpdateData(); + + // Establish offsets + this->vertex_offset = 0; + this->normal_offset = (void*)(3*sizeof(GLfloat)); + this->tangent_offset = (void*)(6*sizeof(GLfloat)); + this->color_offset = (void*)(10*sizeof(GLfloat)); + this->uv_offset = (void*)(11*sizeof(GLfloat)); + this->dummy_offset = (void*)(27*sizeof(GLfloat)); +} + +VBO::~VBO() +{ + glDeleteBuffersARB(1, &this->ibo); + glDeleteBuffersARB(1, &this->vbo_id); + + delete this->vbo; +} + +void VBO::UpdateData() +{ + unsigned int i, j, k; + + glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->vbo_id); + + // Lets the video card know we are done with the old VBO + glBufferDataARB(GL_ARRAY_BUFFER_ARB, 0, NULL, GL_DYNAMIC_DRAW_ARB); + + // Gather data + for (i = 0, j = 0; i < data->m_vertex.size(); i++, j += this->stride/sizeof(GLfloat)) + { + memcpy(&this->vbo[j], data->m_vertex[i].getXYZ(), sizeof(float)*3); + memcpy(&this->vbo[j+3], data->m_vertex[i].getNormal(), sizeof(float)*3); + memcpy(&this->vbo[j+6], data->m_vertex[i].getTangent(), sizeof(float)*4); + memcpy(&this->vbo[j+10], data->m_vertex[i].getRGBA(), sizeof(char)*4); + + for (k = 0; k < RAS_TexVert::MAX_UNIT; k++) + memcpy(&this->vbo[j+11+(k*2)], data->m_vertex[i].getUV(k), sizeof(float)*2); + } + + // Upload Data to GPU + glBufferDataARB(GL_ARRAY_BUFFER_ARB, this->size*this->stride, this->vbo, GL_DYNAMIC_DRAW_ARB); +} + +void VBO::UpdateIndices() +{ + int space = data->m_index.size() * sizeof(GLushort); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, this->ibo); + + // Lets the video card know we are done with the old VBO + glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, NULL, GL_DYNAMIC_DRAW_ARB); + + // Upload Data to VBO + glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, space, &data->m_index[0], GL_DYNAMIC_DRAW_ARB); +} + +void VBO::Draw(int texco_num, RAS_IRasterizer::TexCoGen* texco, int attrib_num, RAS_IRasterizer::TexCoGen* attrib, bool multi) +{ + int unit; + + // Bind buffers + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, this->ibo); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->vbo_id); + + // Vertexes + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, this->stride, this->vertex_offset); + + // Normals + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, this->stride, this->normal_offset); + + // Colors + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(4, GL_UNSIGNED_BYTE, this->stride, this->color_offset); + + if (multi) + { + for (unit = 0; unit < texco_num; ++unit) + { + glClientActiveTexture(GL_TEXTURE0_ARB + unit); + switch (texco[unit]) + { + case RAS_IRasterizer::RAS_TEXCO_ORCO: + case RAS_IRasterizer::RAS_TEXCO_GLOB: + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(3, GL_FLOAT, this->stride, this->vertex_offset); + break; + case RAS_IRasterizer::RAS_TEXCO_UV: + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, this->stride, (void*)((intptr_t)this->uv_offset+(sizeof(GLfloat)*2*unit))); + break; + case RAS_IRasterizer::RAS_TEXCO_NORM: + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(3, GL_FLOAT, this->stride, this->normal_offset); + break; + case RAS_IRasterizer::RAS_TEXTANGENT: + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(4, GL_FLOAT, this->stride, this->tangent_offset); + break; + default: + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(1, GL_SHORT, this->stride, this->dummy_offset); + break; + } + } + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } + else //TexFace + { + glClientActiveTextureARB(GL_TEXTURE0_ARB); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, this->stride, this->uv_offset); + } + + if (GLEW_ARB_vertex_program) + { + int uv = 0; + for (unit = 0; unit < attrib_num; ++unit) + { + switch (attrib[unit]) + { + case RAS_IRasterizer::RAS_TEXCO_ORCO: + case RAS_IRasterizer::RAS_TEXCO_GLOB: + glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, this->stride, this->vertex_offset); + glEnableVertexAttribArrayARB(unit); + break; + case RAS_IRasterizer::RAS_TEXCO_UV: + glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, this->stride, (void*)((intptr_t)this->uv_offset+uv)); + uv += sizeof(GLfloat)*2; + glEnableVertexAttribArrayARB(unit); + break; + case RAS_IRasterizer::RAS_TEXCO_NORM: + glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, stride, this->normal_offset); + glEnableVertexAttribArrayARB(unit); + break; + case RAS_IRasterizer::RAS_TEXTANGENT: + glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, this->stride, this->tangent_offset); + glEnableVertexAttribArrayARB(unit); + break; + default: + break; + } + } + } + + glDrawElements(this->mode, this->indices, GL_UNSIGNED_SHORT, 0); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + if (GLEW_ARB_vertex_program) + { + for (int i = 0; i < attrib_num; ++i) + glDisableVertexAttribArrayARB(i); + } + + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + } + +RAS_StorageVBO::RAS_StorageVBO(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib): + m_texco_num(texco_num), + m_texco(texco), + m_attrib_num(attrib_num), + m_attrib(attrib) +{ +} + +RAS_StorageVBO::~RAS_StorageVBO() +{ +} + +bool RAS_StorageVBO::Init() +{ + return true; +} + +void RAS_StorageVBO::Exit() +{ + m_vbo_lookup.clear(); +} + +void RAS_StorageVBO::IndexPrimitives(RAS_MeshSlot& ms) +{ + IndexPrimitivesInternal(ms, false); +} + +void RAS_StorageVBO::IndexPrimitivesMulti(RAS_MeshSlot& ms) +{ + IndexPrimitivesInternal(ms, true); +} + +void RAS_StorageVBO::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi) +{ + RAS_MeshSlot::iterator it; + VBO *vbo; + + for (ms.begin(it); !ms.end(it); ms.next(it)) + { + vbo = m_vbo_lookup[it.array]; + + if (vbo == 0) + m_vbo_lookup[it.array] = vbo = new VBO(it.array, it.totindex); + + // Update the vbo + if (ms.m_mesh->MeshModified()) + { + vbo->UpdateData(); + } + + vbo->Draw(*m_texco_num, m_texco, *m_attrib_num, m_attrib, multi); + } +} diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.h new file mode 100644 index 00000000000..12c97816e4f --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.h @@ -0,0 +1,102 @@ +/* + * ***** 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_VERTEXBUFFEROBJECTSTORAGE +#define __KX_VERTEXBUFFEROBJECTSTORAGE + +#include +#include "GL/glew.h" + +#include "RAS_IStorage.h" +#include "RAS_IRasterizer.h" + +#include "RAS_OpenGLRasterizer.h" + +class VBO +{ +public: + VBO(RAS_DisplayArray *data, unsigned int indices); + ~VBO(); + + void Draw(int texco_num, RAS_IRasterizer::TexCoGen* texco, int attrib_num, RAS_IRasterizer::TexCoGen* attrib, bool multi); + + void UpdateData(); + void UpdateIndices(); +private: + RAS_DisplayArray* data; + GLuint size; + GLuint stride; + GLuint indices; + GLenum mode; + GLuint ibo; + GLuint vbo_id; + GLfloat* vbo; + + void* vertex_offset; + void* normal_offset; + void* color_offset; + void* tangent_offset; + void* uv_offset; + void* dummy_offset; +}; + +class RAS_StorageVBO : public RAS_IStorage +{ + +public: + RAS_StorageVBO(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib); + virtual ~RAS_StorageVBO(); + + virtual bool Init(); + virtual void Exit(); + + virtual void IndexPrimitives(RAS_MeshSlot& ms); + virtual void IndexPrimitivesMulti(RAS_MeshSlot& ms); + + virtual void SetDrawingMode(int drawingmode){m_drawingmode=drawingmode;}; + +protected: + int m_drawingmode; + + int* m_texco_num; + int* m_attrib_num; + + RAS_IRasterizer::TexCoGen* m_texco; + RAS_IRasterizer::TexCoGen* m_attrib; + + std::map m_vbo_lookup; + + virtual void IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi); + +#ifdef WITH_CXX_GUARDEDALLOC +public: + void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_StorageVA"); } + void operator delete( void *mem ) { MEM_freeN(mem); } +#endif +}; + +#endif //__KX_VERTEXBUFFEROBJECTSTORAGE diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp deleted file mode 100644 index 3ca5c87e7a8..00000000000 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp +++ /dev/null @@ -1,386 +0,0 @@ -/* - * ***** 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 ***** - */ - -/** \file gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp - * \ingroup bgerastogl - */ - -#include "RAS_VAOpenGLRasterizer.h" -#include - -#include "GL/glew.h" -#include "GPU_extensions.h" - -#include "STR_String.h" -#include "RAS_TexVert.h" -#include "MT_CmMatrix4x4.h" -#include "RAS_IRenderTools.h" // rendering text - -RAS_VAOpenGLRasterizer::RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas, bool lock) -: RAS_OpenGLRasterizer(canvas), - m_Lock(lock && GLEW_EXT_compiled_vertex_array), - m_last_texco_num(0), - m_last_attrib_num(0) -{ -} - -RAS_VAOpenGLRasterizer::~RAS_VAOpenGLRasterizer() -{ -} - -bool RAS_VAOpenGLRasterizer::Init(void) -{ - - bool result = RAS_OpenGLRasterizer::Init(); - - if (result) - { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - } - - return result; -} - -void RAS_VAOpenGLRasterizer::SetDrawingMode(int drawingmode) -{ - m_drawingmode = drawingmode; - - switch (m_drawingmode) - { - case KX_BOUNDINGBOX: - case KX_WIREFRAME: - //glDisableClientState(GL_COLOR_ARRAY); - //glDisable(GL_CULL_FACE); - break; - case KX_SOLID: - //glDisableClientState(GL_COLOR_ARRAY); - break; - case KX_TEXTURED: - case KX_SHADED: - case KX_SHADOW: - //glEnableClientState(GL_COLOR_ARRAY); - default: - break; - } -} - -void RAS_VAOpenGLRasterizer::Exit() -{ - RAS_OpenGLRasterizer::Exit(); -} - -void RAS_VAOpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms) -{ - static const GLsizei stride = sizeof(RAS_TexVert); - bool wireframe = m_drawingmode <= KX_WIREFRAME; - RAS_MeshSlot::iterator it; - GLenum drawmode; - - if (ms.m_pDerivedMesh) { - // cannot be handled here, pass to RAS_OpenGLRasterizer - RAS_OpenGLRasterizer::IndexPrimitivesInternal(ms, false); - return; - } - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - - if (!wireframe) - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - // use glDrawElements to draw each vertexarray - for (ms.begin(it); !ms.end(it); ms.next(it)) { - if (it.totindex == 0) - continue; - - // drawing mode - if (it.array->m_type == RAS_DisplayArray::TRIANGLE) - drawmode = GL_TRIANGLES; - else if (it.array->m_type == RAS_DisplayArray::QUAD) - drawmode = GL_QUADS; - else - drawmode = GL_LINES; - - // colors - if (drawmode != GL_LINES && !wireframe) { - if (ms.m_bObjectColor) { - const MT_Vector4& rgba = ms.m_RGBAcolor; - - glDisableClientState(GL_COLOR_ARRAY); - glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); - } - else { - glColor4f(0.0f, 0.0f, 0.0f, 1.0f); - glEnableClientState(GL_COLOR_ARRAY); - } - } - else - glColor4f(0.0f, 0.0f, 0.0f, 1.0f); - - glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ()); - glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal()); - if (!wireframe) { - glTexCoordPointer(2, GL_FLOAT, stride, it.vertex->getUV1()); - if (glIsEnabled(GL_COLOR_ARRAY)) - glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA()); - } - - // here the actual drawing takes places - glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index); - } - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - - if (!wireframe) { - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - } -} - -void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms) -{ - static const GLsizei stride = sizeof(RAS_TexVert); - bool wireframe = m_drawingmode <= KX_WIREFRAME; - RAS_MeshSlot::iterator it; - GLenum drawmode; - - if (ms.m_pDerivedMesh) { - // cannot be handled here, pass to RAS_OpenGLRasterizer - RAS_OpenGLRasterizer::IndexPrimitivesInternal(ms, true); - return; - } - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - - if (!wireframe) - EnableTextures(true); - - // use glDrawElements to draw each vertexarray - for (ms.begin(it); !ms.end(it); ms.next(it)) { - if (it.totindex == 0) - continue; - - // drawing mode - if (it.array->m_type == RAS_DisplayArray::TRIANGLE) - drawmode = GL_TRIANGLES; - else if (it.array->m_type == RAS_DisplayArray::QUAD) - drawmode = GL_QUADS; - else - drawmode = GL_LINES; - - // colors - if (drawmode != GL_LINES && !wireframe) { - if (ms.m_bObjectColor) { - const MT_Vector4& rgba = ms.m_RGBAcolor; - - glDisableClientState(GL_COLOR_ARRAY); - glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); - } - else { - glColor4f(0.0f, 0.0f, 0.0f, 1.0f); - glEnableClientState(GL_COLOR_ARRAY); - } - } - else - glColor4f(0.0f, 0.0f, 0.0f, 1.0f); - - glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ()); - glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal()); - if (!wireframe) { - TexCoordPtr(it.vertex); - if (glIsEnabled(GL_COLOR_ARRAY)) - glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA()); - } - - // here the actual drawing takes places - glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index); - } - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - - if (!wireframe) { - glDisableClientState(GL_COLOR_ARRAY); - EnableTextures(false); - } -} - -void RAS_VAOpenGLRasterizer::TexCoordPtr(const RAS_TexVert *tv) -{ - /* note: this function must closely match EnableTextures to enable/disable - * the right arrays, otherwise coordinate and attribute pointers from other - * materials can still be used and cause crashes */ - int unit; - - if (GLEW_ARB_multitexture) - { - for (unit=0; unitgetFlag() & RAS_TexVert::SECOND_UV && (int)tv->getUnit() == unit) { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert), tv->getUV2()); - continue; - } - switch(m_texco[unit]) - { - case RAS_TEXCO_ORCO: - case RAS_TEXCO_GLOB: - glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getXYZ()); - break; - case RAS_TEXCO_UV1: - glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV1()); - break; - case RAS_TEXCO_NORM: - glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getNormal()); - break; - case RAS_TEXTANGENT: - glTexCoordPointer(4, GL_FLOAT, sizeof(RAS_TexVert),tv->getTangent()); - break; - case RAS_TEXCO_UV2: - glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV2()); - break; - default: - break; - } - } - - glClientActiveTextureARB(GL_TEXTURE0_ARB); - } - - if (GLEW_ARB_vertex_program) { - for (unit=0; unitgetXYZ()); - break; - case RAS_TEXCO_UV1: - glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV1()); - break; - case RAS_TEXCO_NORM: - glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal()); - break; - case RAS_TEXTANGENT: - glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent()); - break; - case RAS_TEXCO_UV2: - glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV2()); - break; - case RAS_TEXCO_VCOL: - glVertexAttribPointerARB(unit, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(RAS_TexVert), tv->getRGBA()); - break; - default: - break; - } - } - } -} - -void RAS_VAOpenGLRasterizer::EnableTextures(bool enable) -{ - TexCoGen *texco, *attrib; - int unit, texco_num, attrib_num; - - /* we cache last texcoords and attribs to ensure we disable the ones that - * were actually last set */ - if (enable) { - texco = m_texco; - texco_num = m_texco_num; - attrib = m_attrib; - attrib_num = m_attrib_num; - - memcpy(m_last_texco, m_texco, sizeof(TexCoGen)*m_texco_num); - m_last_texco_num = m_texco_num; - memcpy(m_last_attrib, m_attrib, sizeof(TexCoGen)*m_attrib_num); - m_last_attrib_num = m_attrib_num; - } - else { - texco = m_last_texco; - texco_num = m_last_texco_num; - attrib = m_last_attrib; - attrib_num = m_last_attrib_num; - } - - if (GLEW_ARB_multitexture) { - for (unit=0; unitm_uvs[i])); + return ( /* m_flag == other->m_flag && */ /* at the moment the face only stores the smooth/flat setting so don't bother comparing it */ m_rgba == other->m_rgba && MT_fuzzyEqual(MT_Vector3(m_normal), MT_Vector3(other->m_normal)) && MT_fuzzyEqual(MT_Vector3(m_tangent), MT_Vector3(other->m_tangent)) && - MT_fuzzyEqual(MT_Vector2(m_uv1), MT_Vector2(other->m_uv1)) && - MT_fuzzyEqual(MT_Vector2(m_uv2), MT_Vector2(other->m_uv2)) /* && + uv_match /* && MT_fuzzyEqual(MT_Vector3(m_localxyz), MT_Vector3(other->m_localxyz))*/); /* don't bother comparing m_localxyz since we know there from the same vert */ } diff --git a/source/gameengine/Rasterizer/RAS_TexVert.h b/source/gameengine/Rasterizer/RAS_TexVert.h index f76c6a66c86..68074adfede 100644 --- a/source/gameengine/Rasterizer/RAS_TexVert.h +++ b/source/gameengine/Rasterizer/RAS_TexVert.h @@ -48,23 +48,21 @@ class RAS_TexVert { float m_localxyz[3]; // 3*4 = 12 - float m_uv1[2]; // 2*4 = 8 - float m_uv2[2]; // 2*4 = 8 + float m_uvs[8][2]; // 8*2*4=64 //8 = MAX_UNIT unsigned int m_rgba; // 4 - float m_tangent[4]; // 4*4 = 16 - float m_normal[3]; // 3*4 = 12 + float m_tangent[4]; // 4*4 = 16 + float m_normal[3]; // 3*4 = 12 short m_flag; // 2 short m_softBodyIndex; //2 unsigned int m_unit; // 4 unsigned int m_origindex; // 4 //--------- - // 56+6+8+2=72 - // 32 bytes total size, fits nice = 56 = not fit nice. + // 120 + // 32 bytes total size, fits nice = 120 = not fit nice. public: enum { FLAT = 1, - SECOND_UV = 2, MAX_UNIT = 8 }; @@ -74,8 +72,7 @@ public: RAS_TexVert()// :m_xyz(0,0,0),m_uv(0,0),m_rgba(0) {} RAS_TexVert(const MT_Point3& xyz, - const MT_Point2& uv, - const MT_Point2& uv2, + const MT_Point2 uvs[MAX_UNIT], const MT_Vector4& tangent, const unsigned int rgba, const MT_Vector3& normal, @@ -83,12 +80,8 @@ public: const unsigned int origindex); ~RAS_TexVert() {}; - const float* getUV1 () const { - return m_uv1; - }; - - const float* getUV2 () const { - return m_uv2; + const float* getUV (int unit) const { + return m_uvs[unit]; }; const float* getXYZ() const { @@ -123,8 +116,7 @@ public: void SetXYZ(const MT_Point3& xyz); void SetXYZ(const float *xyz); - void SetUV(const MT_Point2& uv); - void SetUV2(const MT_Point2& uv); + void SetUV(int index, const MT_Point2& uv); void SetRGBA(const unsigned int rgba); void SetNormal(const MT_Vector3& normal); diff --git a/source/gameengine/Rasterizer/RAS_texmatrix.cpp b/source/gameengine/Rasterizer/RAS_texmatrix.cpp index 4399265c380..5309dc7feae 100644 --- a/source/gameengine/Rasterizer/RAS_texmatrix.cpp +++ b/source/gameengine/Rasterizer/RAS_texmatrix.cpp @@ -52,9 +52,9 @@ void RAS_CalcTexMatrix(RAS_TexVert p[3],MT_Point3& origin,MT_Vector3& udir,MT_Ve MT_Scalar d = -p[0].xyz().dot(normal); - MT_Matrix3x3 mat3( p[0].getUV1()[0],p[0].getUV1()[1], 1, - p[1].getUV1()[0],p[1].getUV1()[1], 1, - p[2].getUV1()[0],p[2].getUV1()[1], 1); + MT_Matrix3x3 mat3( p[0].getUV(0)[0],p[0].getUV(0)[1], 1, + p[1].getUV(0)[0],p[1].getUV(0)[1], 1, + p[2].getUV(0)[0],p[2].getUV(0)[1], 1); MT_Matrix3x3 mat3inv = mat3.inverse(); -- cgit v1.2.3