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-12-19 00:56:25 +0400
committerMitchell Stokes <mogurijin@gmail.com>2012-12-19 00:56:25 +0400
commitef0473994b6b21aa49bbfab26a483d90d0fef004 (patch)
tree18d9dd7d2fbe6eddaf58f66b6b301c694cb43a50 /source/gameengine/Rasterizer/RAS_OpenGLRasterizer
parent6b2af22d37dc1a039104f2ca0b3b4b56aca7d41c (diff)
BGE: Some as of yet unmerged work I did in the Swiss branch. These changes include:
* Cleaning up the conversion code to avoid a per-face material conversion. Materials are now stored in buckets and only converted if a new material is found. This replaces some of Campbell's earlier work on the subject. His work wasn't as thorough, but it was much safer for a release. * Shaders are only compiled for LibLoaded materials once. Before they could be compiled twice, which could really slow things down. * Refactoring the rasterizer code to use a strategy design pattern to handle different geometry rendering methods such as immediate mode, vertex arrays and vertex buffer objects. VBOs are added, but they will be disabled in a following commit since they are still slower than vertex arrays with display lists. However, VBOs are still useful for mobile, so it's good to keep them around. * Better multi-uv support. The BGE should now be able to handle more than two UV layers, which should help it better match the viewport.
Diffstat (limited to 'source/gameengine/Rasterizer/RAS_OpenGLRasterizer')
-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.cpp298
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h12
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp310
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.h68
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp320
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.h (renamed from source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h)53
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp259
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.h100
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp382
13 files changed, 1223 insertions, 694 deletions
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 d74aa134779..3a60643e9e7 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 a8eb2d5ffdf..0eddde7c203 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 22a700c7d2b..1328a5521b4 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"
@@ -74,7 +78,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),
@@ -93,7 +97,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();
@@ -107,6 +112,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;
+ }
}
@@ -115,10 +138,16 @@ RAS_OpenGLRasterizer::~RAS_OpenGLRasterizer()
{
// Restore the previous AF value
GPU_set_anisotropic(m_prevafvalue);
+ if (m_failsafe_storage && m_failsafe_storage != m_storage)
+ delete m_failsafe_storage;
+
+ if (m_storage)
+ delete m_storage;
}
bool RAS_OpenGLRasterizer::Init()
{
+ bool storage_init;
GPU_state_init();
@@ -146,7 +175,9 @@ bool RAS_OpenGLRasterizer::Init()
glShadeModel(GL_SMOOTH);
- return true;
+ storage_init = m_storage->Init();
+
+ return true && storage_init;
}
@@ -267,6 +298,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);
@@ -289,7 +322,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)
@@ -328,6 +361,8 @@ void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode)
if (m_drawingmode == KX_WIREFRAME)
glDisable(GL_CULL_FACE);
+
+ m_storage->SetDrawingMode(drawingmode);
}
int RAS_OpenGLRasterizer::GetDrawingMode()
@@ -666,7 +701,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,
@@ -708,257 +743,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 88bb0be531b..c156ee53ed3 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..7b38b3b42f3
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp
@@ -0,0 +1,310 @@
+/*
+ * ***** 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"
+
+extern "C"{
+ #include "BLI_utildefines.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_StorageVA.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp
new file mode 100644
index 00000000000..e0d580eff11
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp
@@ -0,0 +1,320 @@
+/*
+ * ***** 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, use_color_array;
+ RAS_MeshSlot::iterator it;
+ GLenum drawmode;
+
+ if (!wireframe)
+ EnableTextures(true);
+ 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]);
+ use_color_array = false;
+ }
+ else {
+ glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+ glEnableClientState(GL_COLOR_ARRAY);
+ use_color_array = true;
+ }
+ }
+ 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 (use_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_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_VAOpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.h
index 6b159db05ed..da7766ec5ca 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.h
@@ -25,46 +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; */ /* UNUSED */
-
- 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
- MEM_CXX_CLASS_ALLOC_FUNCS("GE:RAS_VAOpenGLRasterizer")
+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 /* __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..d40aa98295b
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp
@@ -0,0 +1,259 @@
+/*
+ * ***** 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 = 32*sizeof(GLfloat); // ATI cards really like 32byte aligned VBOs, so we add a little padding
+
+ // 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);
+
+ // 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));
+}
+
+VBO::~VBO()
+{
+ glDeleteBuffersARB(1, &this->ibo);
+ glDeleteBuffersARB(1, &this->vbo_id);
+}
+
+void VBO::UpdateData()
+{
+ unsigned int i, j, k;
+
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->vbo_id);
+ glBufferData(GL_ARRAY_BUFFER, this->stride*this->size, NULL, GL_STATIC_DRAW);
+
+ // Map the buffer
+ GLfloat *vbo_map = (GLfloat*)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+
+ // Gather data
+ for (i = 0, j = 0; i < data->m_vertex.size(); i++, j += this->stride/sizeof(GLfloat))
+ {
+ memcpy(&vbo_map[j], data->m_vertex[i].getXYZ(), sizeof(float)*3);
+ memcpy(&vbo_map[j+3], data->m_vertex[i].getNormal(), sizeof(float)*3);
+ memcpy(&vbo_map[j+6], data->m_vertex[i].getTangent(), sizeof(float)*4);
+ memcpy(&vbo_map[j+10], data->m_vertex[i].getRGBA(), sizeof(char)*4);
+
+ for (k = 0; k < RAS_TexVert::MAX_UNIT; k++)
+ memcpy(&vbo_map[j+11+(k*2)], data->m_vertex[i].getUV(k), sizeof(float)*2);
+ }
+
+ glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
+}
+
+void VBO::UpdateIndices()
+{
+ int space = data->m_index.size() * sizeof(GLushort);
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, this->ibo);
+
+ // Upload Data to VBO
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, space, &data->m_index[0], GL_STATIC_DRAW);
+}
+
+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:
+ 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..d8d8192e482
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.h
@@ -0,0 +1,100 @@
+/*
+ * ***** 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;
+
+ void* vertex_offset;
+ void* normal_offset;
+ void* color_offset;
+ void* tangent_offset;
+ void* uv_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_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp
deleted file mode 100644
index 076acb0d153..00000000000
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp
+++ /dev/null
@@ -1,382 +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 <stdlib.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), */ /* UNUSED */
- 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)
- {
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-
- 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()
-{
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
-
- 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;
- }
-
- 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);
- }
-
- 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;
- }
-
- 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_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; 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]) {
- 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; 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;
- }
- }
- }
-}
-
-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; unit<texco_num; unit++) {
- glClientActiveTextureARB(GL_TEXTURE0_ARB+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;
- }
- }
-
- 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_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;
- }
- }
- }
-
- if (!enable) {
- m_last_texco_num = 0;
- m_last_attrib_num = 0;
- }
-}
-