Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitchell Stokes <mogurijin@gmail.com>2012-05-29 11:12:12 +0400
committerMitchell Stokes <mogurijin@gmail.com>2012-05-29 11:12:12 +0400
commit0e98380bf45253a74fbd70c421105ce486acf58d (patch)
tree666a272594f7cf8bf39c0e4d74b313c3ed7300a1 /source/gameengine/Rasterizer
parentb5b7455bad02064b2c19aa85222804184b236521 (diff)
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.
Diffstat (limited to 'source/gameengine/Rasterizer')
-rw-r--r--source/gameengine/Rasterizer/RAS_IRasterizer.h4
-rw-r--r--source/gameengine/Rasterizer/RAS_MaterialBucket.cpp9
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.cpp5
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.h3
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt9
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_IStorage.h62
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp38
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h6
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp293
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h12
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp307
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.h68
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp (renamed from source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp)259
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.h (renamed from source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h)52
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp272
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.h102
-rw-r--r--source/gameengine/Rasterizer/RAS_TexVert.cpp26
-rw-r--r--source/gameengine/Rasterizer/RAS_TexVert.h26
-rw-r--r--source/gameengine/Rasterizer/RAS_texmatrix.cpp6
19 files changed, 1038 insertions, 521 deletions
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<unsigned short> KX_IndexArray;
typedef vector<RAS_TexVert> 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 <vector>
#include <map>
@@ -49,7 +49,7 @@ typedef std::map<RAS_DisplayArrayList, RAS_ListSlot*> RAS_ArrayLists;
typedef std::vector<RAS_ListSlot*> RAS_ListSlots; // indexed by material slot number
typedef std::map<DerivedMesh*, RAS_ListSlots*> 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; unit<m_attrib_num; unit++)
- if (m_attrib[unit] == RAS_TEXCO_UV1)
+ if (m_attrib[unit] == RAS_TEXCO_UV)
glattrib = unit;
rendertools->RenderText(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; unit<m_texco_num; unit++) {
- if (tv.getFlag() & RAS_TexVert::SECOND_UV && (int)tv.getUnit() == unit) {
- glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
- continue;
- }
- switch(m_texco[unit]) {
- case RAS_TEXCO_ORCO:
- case RAS_TEXCO_GLOB:
- glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getXYZ());
- break;
- case RAS_TEXCO_UV1:
- glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV1());
- break;
- case RAS_TEXCO_NORM:
- glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getNormal());
- break;
- case RAS_TEXTANGENT:
- glMultiTexCoord4fvARB(GL_TEXTURE0_ARB+unit, tv.getTangent());
- break;
- case RAS_TEXCO_UV2:
- glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
- break;
- default:
- break;
- }
- }
- }
-
- if (GLEW_ARB_vertex_program) {
- for (unit=0; unit<m_attrib_num; unit++) {
- switch(m_attrib[unit]) {
- case RAS_TEXCO_ORCO:
- case RAS_TEXCO_GLOB:
- glVertexAttrib3fvARB(unit, tv.getXYZ());
- break;
- case RAS_TEXCO_UV1:
- glVertexAttrib2fvARB(unit, tv.getUV1());
- break;
- case RAS_TEXCO_NORM:
- glVertexAttrib3fvARB(unit, tv.getNormal());
- break;
- case RAS_TEXTANGENT:
- glVertexAttrib4fvARB(unit, tv.getTangent());
- break;
- case RAS_TEXCO_UV2:
- glVertexAttrib2fvARB(unit, tv.getUV2());
- break;
- case RAS_TEXCO_VCOL:
- glVertexAttrib4ubvARB(unit, tv.getRGBA());
- break;
- default:
- break;
- }
- }
- }
-
-}
-
void RAS_OpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
{
- IndexPrimitivesInternal(ms, false);
+ if (ms.m_pDerivedMesh)
+ m_failsafe_storage->IndexPrimitives(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, &current_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), &current_gpu_attribs);
- else
- memset(&current_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->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, &current_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), &current_gpu_attribs);
+ else
+ memset(&current_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_VAOpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp
index 3ca5c87e7a8..d32932cfeec 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp
@@ -25,92 +25,46 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp
- * \ingroup bgerastogl
- */
-
-#include "RAS_VAOpenGLRasterizer.h"
-#include <stdlib.h>
+#include "RAS_StorageVA.h"
#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),
+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_VAOpenGLRasterizer::~RAS_VAOpenGLRasterizer()
+RAS_StorageVA::~RAS_StorageVA()
{
}
-bool RAS_VAOpenGLRasterizer::Init(void)
+bool RAS_StorageVA::Init()
{
-
- bool result = RAS_OpenGLRasterizer::Init();
-
- if (result)
- {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- }
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- return result;
+ return true;
}
-void RAS_VAOpenGLRasterizer::SetDrawingMode(int drawingmode)
+void RAS_StorageVA::Exit()
{
- 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)
+void RAS_StorageVA::IndexPrimitives(RAS_MeshSlot& ms)
{
static const GLsizei stride = sizeof(RAS_TexVert);
- bool wireframe = m_drawingmode <= KX_WIREFRAME;
+ bool wireframe = m_drawingmode <= RAS_IRasterizer::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);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
// use glDrawElements to draw each vertexarray
for (ms.begin(it); !ms.end(it); ms.next(it)) {
@@ -144,7 +98,7 @@ void RAS_VAOpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
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());
+ glTexCoordPointer(2, GL_FLOAT, stride, it.vertex->getUV(0));
if (glIsEnabled(GL_COLOR_ARRAY))
glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA());
}
@@ -152,32 +106,22 @@ void RAS_VAOpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
// 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)
+void RAS_StorageVA::IndexPrimitivesMulti(class RAS_MeshSlot& ms)
{
static const GLsizei stride = sizeof(RAS_TexVert);
- bool wireframe = m_drawingmode <= KX_WIREFRAME;
+ bool wireframe = m_drawingmode <= RAS_IRasterizer::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);
@@ -222,16 +166,13 @@ void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
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)
+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
@@ -240,34 +181,26 @@ void RAS_VAOpenGLRasterizer::TexCoordPtr(const RAS_TexVert *tv)
if (GLEW_ARB_multitexture)
{
- for (unit=0; unit<m_texco_num; unit++)
+ for (unit = 0; unit < *m_texco_num; unit++)
{
glClientActiveTextureARB(GL_TEXTURE0_ARB+unit);
- if (tv->getFlag() & 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])
+ 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;
+ 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;
}
}
@@ -275,51 +208,49 @@ void RAS_VAOpenGLRasterizer::TexCoordPtr(const RAS_TexVert *tv)
}
if (GLEW_ARB_vertex_program) {
- for (unit=0; unit<m_attrib_num; unit++) {
- switch(m_attrib[unit]) {
- case RAS_TEXCO_ORCO:
- case RAS_TEXCO_GLOB:
- glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getXYZ());
- 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;
+ 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_VAOpenGLRasterizer::EnableTextures(bool enable)
+void RAS_StorageVA::EnableTextures(bool enable)
{
- TexCoGen *texco, *attrib;
+ 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;
+ texco_num = *m_texco_num;
attrib = m_attrib;
- attrib_num = m_attrib_num;
+ 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;
+ 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;
@@ -329,23 +260,22 @@ void RAS_VAOpenGLRasterizer::EnableTextures(bool enable)
}
if (GLEW_ARB_multitexture) {
- for (unit=0; unit<texco_num; unit++) {
- glClientActiveTextureARB(GL_TEXTURE0_ARB+unit);
+ for (unit = 0; unit < texco_num; unit++) {
+ glClientActiveTextureARB(GL_TEXTURE0_ARB + unit);
- switch(texco[unit])
+ switch (texco[unit])
{
- case RAS_TEXCO_ORCO:
- case RAS_TEXCO_GLOB:
- case RAS_TEXCO_UV1:
- case RAS_TEXCO_NORM:
- case RAS_TEXTANGENT:
- case RAS_TEXCO_UV2:
- if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- break;
- default:
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- break;
+ 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;
}
}
@@ -359,21 +289,20 @@ void RAS_VAOpenGLRasterizer::EnableTextures(bool enable)
}
if (GLEW_ARB_vertex_program) {
- for (unit=0; unit<attrib_num; unit++) {
- switch(attrib[unit]) {
- case RAS_TEXCO_ORCO:
- case RAS_TEXCO_GLOB:
- case RAS_TEXCO_UV1:
- case RAS_TEXCO_NORM:
- case RAS_TEXTANGENT:
- case RAS_TEXCO_UV2:
- case RAS_TEXCO_VCOL:
- if (enable) glEnableVertexAttribArrayARB(unit);
- else glDisableVertexAttribArrayARB(unit);
- break;
- default:
- glDisableVertexAttribArrayARB(unit);
- break;
+ 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;
}
}
}
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.h
index d96f390ad74..da7766ec5ca 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.h
@@ -25,49 +25,53 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file RAS_VAOpenGLRasterizer.h
- * \ingroup bgerastogl
- */
+#ifndef __KX_VERTEXARRAYSTORAGE
+#define __KX_VERTEXARRAYSTORAGE
-#ifndef __RAS_VAOPENGLRASTERIZER_H__
-#define __RAS_VAOPENGLRASTERIZER_H__
+#include "RAS_IStorage.h"
+#include "RAS_IRasterizer.h"
#include "RAS_OpenGLRasterizer.h"
-class RAS_VAOpenGLRasterizer : public RAS_OpenGLRasterizer
+class RAS_StorageVA : public RAS_IStorage
{
- void TexCoordPtr(const RAS_TexVert *tv);
- bool m_Lock;
-
- TexCoGen m_last_texco[RAS_MAX_TEXCO];
- TexCoGen m_last_attrib[RAS_MAX_ATTRIB];
- int m_last_texco_num;
- int m_last_attrib_num;
public:
- RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas, bool lock=false);
- virtual ~RAS_VAOpenGLRasterizer();
+ 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 SetDrawingMode(int drawingmode);
-
- virtual void IndexPrimitives(class RAS_MeshSlot& ms);
+ virtual void IndexPrimitives(RAS_MeshSlot& ms);
virtual void IndexPrimitivesMulti(class RAS_MeshSlot& ms);
-private:
+ 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 bool QueryArrays(){return true;}
- //virtual bool QueryLists(){return m_Lock;}
+ 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_VAOpenGLRasterizer"); }
+ 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 //__RAS_VAOPENGLRASTERIZER_H__
-
+#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 <map>
+#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<RAS_DisplayArray*, class VBO*> 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_TexVert.cpp b/source/gameengine/Rasterizer/RAS_TexVert.cpp
index f74aa24232b..a848bce410a 100644
--- a/source/gameengine/Rasterizer/RAS_TexVert.cpp
+++ b/source/gameengine/Rasterizer/RAS_TexVert.cpp
@@ -34,8 +34,7 @@
#include "MT_Matrix4x4.h"
RAS_TexVert::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,
@@ -43,8 +42,6 @@ RAS_TexVert::RAS_TexVert(const MT_Point3& xyz,
const unsigned int origindex)
{
xyz.getValue(m_localxyz);
- uv.getValue(m_uv1);
- uv2.getValue(m_uv2);
SetRGBA(rgba);
SetNormal(normal);
tangent.getValue(m_tangent);
@@ -52,6 +49,11 @@ RAS_TexVert::RAS_TexVert(const MT_Point3& xyz,
m_origindex = origindex;
m_unit = 2;
m_softBodyIndex = -1;
+
+ for (int i = 0; i < MAX_UNIT; ++i)
+ {
+ uvs[i].getValue(m_uvs[i]);
+ }
}
const MT_Point3& RAS_TexVert::xyz()
@@ -80,14 +82,9 @@ void RAS_TexVert::SetXYZ(const float *xyz)
m_localxyz[0]= xyz[0]; m_localxyz[1]= xyz[1]; m_localxyz[2]= xyz[2];
}
-void RAS_TexVert::SetUV(const MT_Point2& uv)
+void RAS_TexVert::SetUV(int index, const MT_Point2& uv)
{
- uv.getValue(m_uv1);
-}
-
-void RAS_TexVert::SetUV2(const MT_Point2& uv)
-{
- uv.getValue(m_uv2);
+ uv.getValue(m_uvs[index]);
}
@@ -121,14 +118,17 @@ void RAS_TexVert::SetTangent(const MT_Vector3& tangent)
// compare two vertices, and return TRUE if both are almost identical (they can be shared)
bool RAS_TexVert::closeTo(const RAS_TexVert* other)
{
+ bool uv_match = true;
+ for (int i=0; i<MAX_UNIT; i++)
+ uv_match = uv_match && MT_fuzzyEqual(MT_Vector2(m_uvs[i]), MT_Vector2(other->m_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();