diff options
Diffstat (limited to 'source/gameengine/Rasterizer')
40 files changed, 1961 insertions, 1011 deletions
diff --git a/source/gameengine/Rasterizer/CMakeLists.txt b/source/gameengine/Rasterizer/CMakeLists.txt index ddc72c08ea1..1299def8070 100644 --- a/source/gameengine/Rasterizer/CMakeLists.txt +++ b/source/gameengine/Rasterizer/CMakeLists.txt @@ -30,6 +30,8 @@ set(INC ../SceneGraph ../../blender/makesdna ../../blender/blenkernel + ../../blender/blenlib + ../../blender/gpu ../../../intern/container ../../../intern/guardedalloc ../../../intern/moto/include diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp index cf869e71945..49cc9de5118 100644 --- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp +++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp @@ -24,8 +24,7 @@ * \ingroup bgerast */ - -#define STRINGIFY(A) #A +#include "BLI_utildefines.h" /* for STRINGIFY */ #include "RAS_OpenGLFilters/RAS_Blur2DFilter.h" #include "RAS_OpenGLFilters/RAS_Sharpen2DFilter.h" @@ -42,20 +41,23 @@ #include "RAS_ICanvas.h" #include "RAS_Rect.h" #include "RAS_2DFilterManager.h" -#include <iostream> -#include "GL/glew.h" +#include "Value.h" -#include <stdio.h> +#include "GPU_compatibility.h" +#include "GPU_functions.h" +#include "GPU_colors.h" +#include "GPU_extensions.h" -#include "Value.h" +#include <iostream> +#include <stdio.h> RAS_2DFilterManager::RAS_2DFilterManager(): texturewidth(-1), textureheight(-1), /* numberoffilters(0), */ /* UNUSED */ need_tex_update(true) { - isshadersupported = GLEW_ARB_shader_objects && - GLEW_ARB_fragment_shader && GLEW_ARB_multitexture; + isshadersupported = GPU_EXT_GLSL_ENABLED && + GPU_EXT_GLSL_FRAGMENT_ENABLED && GLEW_ARB_multitexture; /* used to return before 2.49 but need to initialize values so don't */ if (!isshadersupported) @@ -80,7 +82,7 @@ RAS_2DFilterManager::~RAS_2DFilterManager() void RAS_2DFilterManager::PrintShaderErrors(unsigned int shader, const char *task, const char *code) { - GLcharARB log[5000]; + GLchar log[5000]; GLsizei length = 0; const char *c, *pos, *end; int line = 1; @@ -90,7 +92,7 @@ void RAS_2DFilterManager::PrintShaderErrors(unsigned int shader, const char *tas errorprinted= true; - glGetInfoLogARB(shader, sizeof(log), &length, log); + gpu_glGetShaderInfoLog(shader, sizeof(log), &length, log); end = code + strlen(code); printf("2D Filter GLSL Shader: %s error:\n", task); @@ -111,27 +113,28 @@ void RAS_2DFilterManager::PrintShaderErrors(unsigned int shader, const char *tas unsigned int RAS_2DFilterManager::CreateShaderProgram(const char* shadersource) { GLuint program = 0; - GLuint fShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER); + GLuint fShader = gpu_glCreateShader(GL_FRAGMENT_SHADER); GLint success; - glShaderSourceARB(fShader, 1, (const char**)&shadersource, NULL); + gpu_glShaderSource(fShader, 1, (const char**)&shadersource, NULL); - glCompileShaderARB(fShader); + gpu_glCompileShader(fShader); - glGetObjectParameterivARB(fShader, GL_COMPILE_STATUS, &success); + gpu_glGetShaderiv(fShader, GL_COMPILE_STATUS, &success); if (!success) { /*Shader Comile Error*/ PrintShaderErrors(fShader, "compile", shadersource); return 0; } + /* We still need vertrx shader for ES and OpenGL 3.0+ */ - program = glCreateProgramObjectARB(); - glAttachObjectARB(program, fShader); + program = gpu_glCreateProgram(); + gpu_glAttachShader(program, fShader); - glLinkProgramARB(program); - glGetObjectParameterivARB(program, GL_LINK_STATUS, &success); + gpu_glLinkProgram(program); + gpu_glGetProgramiv(program, GL_LINK_STATUS, &success); if (!success) { /*Program Link Error*/ @@ -139,8 +142,8 @@ unsigned int RAS_2DFilterManager::CreateShaderProgram(const char* shadersource) return 0; } - glValidateProgramARB(program); - glGetObjectParameterivARB(program, GL_VALIDATE_STATUS, &success); + gpu_glValidateProgram(program); + gpu_glGetProgramiv(program, GL_VALIDATE_STATUS, &success); if (!success) { /*Program Validation Error*/ @@ -153,7 +156,8 @@ unsigned int RAS_2DFilterManager::CreateShaderProgram(const char* shadersource) unsigned int RAS_2DFilterManager::CreateShaderProgram(int filtermode) { - switch (filtermode) { + switch(filtermode) + { case RAS_2DFILTER_BLUR: return CreateShaderProgram(BlurFragmentShader); case RAS_2DFILTER_SHARPEN: @@ -181,12 +185,12 @@ unsigned int RAS_2DFilterManager::CreateShaderProgram(int filtermode) void RAS_2DFilterManager::AnalyseShader(int passindex, vector<STR_String>& propNames) { texflag[passindex] = 0; - if (glGetUniformLocationARB(m_filters[passindex], "bgl_DepthTexture") != -1) + if (gpu_glGetUniformLocation(m_filters[passindex], "bgl_DepthTexture") != -1) { if (GLEW_ARB_depth_texture) texflag[passindex] |= 0x1; } - if (glGetUniformLocationARB(m_filters[passindex], "bgl_LuminanceTexture") != -1) + if (gpu_glGetUniformLocation(m_filters[passindex], "bgl_LuminanceTexture") != -1) { texflag[passindex] |= 0x2; } @@ -196,7 +200,7 @@ void RAS_2DFilterManager::AnalyseShader(int passindex, vector<STR_String>& propN int objProperties = propNames.size(); int i; for (i=0; i<objProperties; i++) - if (glGetUniformLocationARB(m_filters[passindex], propNames[i]) != -1) + if (gpu_glGetUniformLocation(m_filters[passindex], propNames[i]) != -1) m_properties[passindex].push_back(propNames[i]); } } @@ -204,71 +208,71 @@ void RAS_2DFilterManager::AnalyseShader(int passindex, vector<STR_String>& propN void RAS_2DFilterManager::StartShaderProgram(int passindex) { GLint uniformLoc; - glUseProgramObjectARB(m_filters[passindex]); - uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_RenderedTexture"); + gpu_glUseProgram(m_filters[passindex]); + uniformLoc = gpu_glGetUniformLocation(m_filters[passindex], "bgl_RenderedTexture"); glActiveTextureARB(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texname[0]); if (uniformLoc != -1) { - glUniform1iARB(uniformLoc, 0); + gpu_glUniform1i(uniformLoc, 0); } /* send depth texture to glsl program if it needs */ if (texflag[passindex] & 0x1) { - uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_DepthTexture"); + uniformLoc = gpu_glGetUniformLocation(m_filters[passindex], "bgl_DepthTexture"); glActiveTextureARB(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texname[1]); if (uniformLoc != -1) { - glUniform1iARB(uniformLoc, 1); + gpu_glUniform1i(uniformLoc, 1); } } /* send luminance texture to glsl program if it needs */ if (texflag[passindex] & 0x2) { - uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_LuminanceTexture"); + uniformLoc = gpu_glGetUniformLocation(m_filters[passindex], "bgl_LuminanceTexture"); glActiveTextureARB(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, texname[2]); if (uniformLoc != -1) { - glUniform1iARB(uniformLoc, 2); + gpu_glUniform1i(uniformLoc, 2); } } - uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_TextureCoordinateOffset"); + uniformLoc = gpu_glGetUniformLocation(m_filters[passindex], "bgl_TextureCoordinateOffset"); if (uniformLoc != -1) { - glUniform2fvARB(uniformLoc, 9, textureoffsets); + gpu_glUniform2fv(uniformLoc, 9, textureoffsets); } - uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_RenderedTextureWidth"); + uniformLoc = gpu_glGetUniformLocation(m_filters[passindex], "bgl_RenderedTextureWidth"); if (uniformLoc != -1) { - glUniform1fARB(uniformLoc,texturewidth); + gpu_glUniform1f(uniformLoc,texturewidth); } - uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_RenderedTextureHeight"); + uniformLoc = gpu_glGetUniformLocation(m_filters[passindex], "bgl_RenderedTextureHeight"); if (uniformLoc != -1) { - glUniform1fARB(uniformLoc,textureheight); + gpu_glUniform1f(uniformLoc,textureheight); } int i, objProperties = m_properties[passindex].size(); for (i=0; i<objProperties; i++) { - uniformLoc = glGetUniformLocationARB(m_filters[passindex], m_properties[passindex][i]); + uniformLoc = gpu_glGetUniformLocation(m_filters[passindex], m_properties[passindex][i]); if (uniformLoc != -1) { float value = ((CValue*)m_gameObjects[passindex])->GetPropertyNumber(m_properties[passindex][i], 0.0); - glUniform1fARB(uniformLoc,value); + gpu_glUniform1f(uniformLoc,value); } } } void RAS_2DFilterManager::EndShaderProgram() { - glUseProgramObjectARB(0); + gpu_glUseProgram(0); } void RAS_2DFilterManager::FreeTextures() @@ -429,20 +433,24 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas) // reverting to texunit 0, without this we get bug [#28462] glActiveTextureARB(GL_TEXTURE0); - glViewport(rect.GetLeft(), rect.GetBottom(), rect_width, rect_height); + gpuViewport(rect.GetLeft(), rect.GetBottom(), rect_width, rect_height); glDisable(GL_DEPTH_TEST); // in case the previous material was wire glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // if the last rendered face had alpha add it would messes with the color of the plane we apply 2DFilter to glDisable(GL_BLEND); - glPushMatrix(); //GL_MODELVIEW - glLoadIdentity(); // GL_MODELVIEW - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); + gpuPushMatrix(); //GL_MODELVIEW + gpuLoadIdentity(); // GL_MODELVIEW + + gpuMatrixMode(GL_TEXTURE); + gpuLoadIdentity(); + + gpuMatrixMode(GL_PROJECTION); + gpuPushMatrix(); + gpuLoadIdentity(); + + gpuMatrixCommit(); for (passindex =0; passindex<MAX_RENDER_PASS; passindex++) { @@ -453,24 +461,51 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas) glActiveTextureARB(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texname[0]); glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rect.GetLeft(), rect.GetBottom(), rect_width, rect_height, 0); // Don't use texturewidth and textureheight in case we don't have NPOT support - glClear(GL_COLOR_BUFFER_BIT); - - glBegin(GL_QUADS); - glColor4f(1.f, 1.f, 1.f, 1.f); - glTexCoord2f(1.0, 1.0); glMultiTexCoord2fARB(GL_TEXTURE3_ARB, canvascoord[1], canvascoord[3]); glVertex2f(1,1); - glTexCoord2f(0.0, 1.0); glMultiTexCoord2fARB(GL_TEXTURE3_ARB, canvascoord[0], canvascoord[3]); glVertex2f(-1,1); - glTexCoord2f(0.0, 0.0); glMultiTexCoord2fARB(GL_TEXTURE3_ARB, canvascoord[0], canvascoord[2]); glVertex2f(-1,-1); - glTexCoord2f(1.0, 0.0); glMultiTexCoord2fARB(GL_TEXTURE3_ARB, canvascoord[1], canvascoord[2]); glVertex2f(1,-1); - glEnd(); + gpuClear(GL_COLOR_BUFFER_BIT); + + gpuCurrentColor3x(CPACK_WHITE); + + { + GLenum map[2] = { GL_TEXTURE0, GL_TEXTURE3 }; + GLint sizes[2] = { 2, 2 }; + + gpuImmediateElementSizes(2, 0, 0); + gpuImmediateTextureUnitCount(2); + gpuImmediateTextureUnitMap(map); + gpuImmediateTexCoordSizes(sizes); + } + + gpuImmediateLock(); + gpuBegin(GL_TRIANGLE_FAN); + gpuTexCoord2f(1, 1); + gpuMultiTexCoord2f(1, canvascoord[1], canvascoord[3]); + gpuVertex2f( 1, 1); + + gpuTexCoord2f(0, 1); + gpuMultiTexCoord2f(1, canvascoord[0], canvascoord[3]); + gpuVertex2f(-1, 1); + + gpuTexCoord2f(0, 0); + gpuMultiTexCoord2f(1, canvascoord[0], canvascoord[2]); + gpuVertex2f(-1,-1); + + gpuTexCoord2f(1, 0); + gpuMultiTexCoord2f(1, canvascoord[1], canvascoord[2]); + gpuVertex2f( 1,-1); + gpuEnd(); + gpuImmediateUnlock(); } } glEnable(GL_DEPTH_TEST); - glViewport(viewport[0],viewport[1],viewport[2],viewport[3]); + gpuViewport(viewport[0],viewport[1],viewport[2],viewport[3]); EndShaderProgram(); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); + gpuPopMatrix(); + + gpuMatrixMode(GL_MODELVIEW); + gpuPopMatrix(); + + gpuMatrixCommit(); } void RAS_2DFilterManager::EnableFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFILTER_MODE mode, int pass, STR_String& text) @@ -495,7 +530,7 @@ void RAS_2DFilterManager::EnableFilter(vector<STR_String>& propNames, void* game if (mode == RAS_2DFILTER_NOFILTER) { if (m_filters[pass]) - glDeleteObjectARB(m_filters[pass]); + gpu_glDeleteProgram(m_filters[pass]); m_enabled[pass] = 0; m_filters[pass] = 0; m_gameObjects[pass] = NULL; @@ -507,7 +542,7 @@ void RAS_2DFilterManager::EnableFilter(vector<STR_String>& propNames, void* game if (mode == RAS_2DFILTER_CUSTOMFILTER) { if (m_filters[pass]) - glDeleteObjectARB(m_filters[pass]); + gpu_glDeleteProgram(m_filters[pass]); m_filters[pass] = CreateShaderProgram(text.Ptr()); m_gameObjects[pass] = gameObj; AnalyseShader(pass, propNames); @@ -517,7 +552,7 @@ void RAS_2DFilterManager::EnableFilter(vector<STR_String>& propNames, void* game // We've checked all other cases, which means we must be dealing with a builtin filter if (m_filters[pass]) - glDeleteObjectARB(m_filters[pass]); + gpu_glDeleteProgram(m_filters[pass]); m_filters[pass] = CreateShaderProgram(mode); m_gameObjects[pass] = NULL; AnalyseShader(pass, propNames); diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.cpp b/source/gameengine/Rasterizer/RAS_BucketManager.cpp index f24e3397801..7d251fc7fad 100644 --- a/source/gameengine/Rasterizer/RAS_BucketManager.cpp +++ b/source/gameengine/Rasterizer/RAS_BucketManager.cpp @@ -29,11 +29,13 @@ * \ingroup bgerast */ -#ifdef _MSC_VER - /* don't show these anoying STL warnings */ -# pragma warning (disable:4786) + +#if defined(WIN32) && !defined(FREE_WINDOWS) +// don't show these anoying STL warnings +#pragma warning (disable:4786) #endif +#include "CTR_Map.h" #include "RAS_MaterialBucket.h" #include "STR_HashedString.h" #include "RAS_MeshObject.h" @@ -128,7 +130,7 @@ void RAS_BucketManager::OrderBuckets(const MT_Transform& cameratrans, BucketList RAS_MaterialBucket* bucket = *bit; RAS_MeshSlot* ms; // remove the mesh slot form the list, it culls them automatically for next frame - while ((ms = bucket->GetNextActiveMeshSlot())) { + while((ms = bucket->GetNextActiveMeshSlot())) { slots[i++].set(ms, bucket, pnorm); } } @@ -155,7 +157,7 @@ void RAS_BucketManager::RenderAlphaBuckets( for (sit=slots.begin(); sit!=slots.end(); ++sit) { rendertools->SetClientObject(rasty, sit->m_ms->m_clientObj); - while (sit->m_bucket->ActivateMaterial(cameratrans, rasty, rendertools)) + while(sit->m_bucket->ActivateMaterial(cameratrans, rasty, rendertools)) sit->m_bucket->RenderMeshSlot(cameratrans, rasty, rendertools, *(sit->m_ms)); // make this mesh slot culled automatically for next frame @@ -178,7 +180,8 @@ void RAS_BucketManager::RenderSolidBuckets( RAS_MaterialBucket* bucket = *bit; RAS_MeshSlot* ms; // remove the mesh slot form the list, it culls them automatically for next frame - while ((ms = bucket->GetNextActiveMeshSlot())) { + while((ms = bucket->GetNextActiveMeshSlot())) + { rendertools->SetClientObject(rasty, ms->m_clientObj); while (bucket->ActivateMaterial(cameratrans, rasty, rendertools)) bucket->RenderMeshSlot(cameratrans, rasty, rendertools, *ms); @@ -217,7 +220,7 @@ void RAS_BucketManager::RenderSolidBuckets( for (sit=slots.begin(); sit!=slots.end(); ++sit) { rendertools->SetClientObject(rasty, sit->m_ms->m_clientObj); - while (sit->m_bucket->ActivateMaterial(cameratrans, rasty, rendertools)) + while(sit->m_bucket->ActivateMaterial(cameratrans, rasty, rendertools)) sit->m_bucket->RenderMeshSlot(cameratrans, rasty, rendertools, *(sit->m_ms)); } #endif @@ -232,6 +235,24 @@ void RAS_BucketManager::Renderbuckets( RenderSolidBuckets(cameratrans, rasty, rendertools); RenderAlphaBuckets(cameratrans, rasty, rendertools); + /* All meshes should be up to date now */ + /* Don't do this while processing buckets because some meshes are split between buckets */ + BucketList::iterator bit; + list<RAS_MeshSlot>::iterator mit; + for (bit = m_SolidBuckets.begin(); bit != m_SolidBuckets.end(); ++bit) { + RAS_MaterialBucket* bucket = *bit; + for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) { + mit->m_mesh->SetMeshModified(false); + } + } + for (bit = m_AlphaBuckets.begin(); bit != m_AlphaBuckets.end(); ++bit) { + RAS_MaterialBucket* bucket = *bit; + for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) { + mit->m_mesh->SetMeshModified(false); + } + } + + rendertools->SetClientObject(rasty, NULL); } diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.h b/source/gameengine/Rasterizer/RAS_BucketManager.h index 78125a7bbb3..2650bc9f722 100644 --- a/source/gameengine/Rasterizer/RAS_BucketManager.h +++ b/source/gameengine/Rasterizer/RAS_BucketManager.h @@ -34,6 +34,7 @@ #include "MT_Transform.h" #include "RAS_MaterialBucket.h" +#include "CTR_Map.h" #include <vector> @@ -89,4 +90,5 @@ private: #endif }; -#endif /* __RAS_BUCKETMANAGER_H__ */ +#endif //__RAS_BUCKETMANAGER_H__ + diff --git a/source/gameengine/Rasterizer/RAS_CameraData.h b/source/gameengine/Rasterizer/RAS_CameraData.h index 7a6bb541a1a..4a70df6e505 100644 --- a/source/gameengine/Rasterizer/RAS_CameraData.h +++ b/source/gameengine/Rasterizer/RAS_CameraData.h @@ -71,4 +71,5 @@ struct RAS_CameraData } }; -#endif /* __RAS_CAMERADATA_H__ */ +#endif //__RAS_CAMERADATA_H__ + diff --git a/source/gameengine/Rasterizer/RAS_Deformer.h b/source/gameengine/Rasterizer/RAS_Deformer.h index 058f2304f3d..d70e56dc285 100644 --- a/source/gameengine/Rasterizer/RAS_Deformer.h +++ b/source/gameengine/Rasterizer/RAS_Deformer.h @@ -32,9 +32,9 @@ #ifndef __RAS_DEFORMER_H__ #define __RAS_DEFORMER_H__ -#ifdef _MSC_VER -# pragma warning (disable:4786) /* get rid of stupid stl-visual compiler debug warning */ -#endif +#if defined(WIN32) && !defined(FREE_WINDOWS) +#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning +#endif //WIN32 #include <stdlib.h> #include "CTR_Map.h" diff --git a/source/gameengine/Rasterizer/RAS_ICanvas.h b/source/gameengine/Rasterizer/RAS_ICanvas.h index 60b9f052075..f045eb7e423 100644 --- a/source/gameengine/Rasterizer/RAS_ICanvas.h +++ b/source/gameengine/Rasterizer/RAS_ICanvas.h @@ -59,7 +59,7 @@ public: virtual ~RAS_ICanvas( ) { - } + }; virtual void @@ -231,4 +231,5 @@ protected: #endif }; -#endif /* __RAS_ICANVAS_H__ */ +#endif //__RAS_ICANVAS_H__ + diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp index ddadd97b567..4af1753c2da 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp @@ -254,18 +254,12 @@ bool RAS_IPolyMaterial::UsesLighting(RAS_IRasterizer *rasty) const { bool dolights = false; - if (m_flag & RAS_BLENDERMAT) { - dolights = (m_flag & RAS_MULTILIGHT) != 0; - } - else if (rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID) { - /* pass */ - } - else if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW) { - /* pass */ - } - else { + if (m_flag & RAS_BLENDERMAT) + dolights = (m_flag &RAS_MULTILIGHT)!=0; + else if (rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID); + else if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW); + else dolights = m_light; - } return dolights; } diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h index 9fffc8bebc9..6e044cb7cf4 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h @@ -184,7 +184,7 @@ public: /* * PreCalculate texture gen */ - virtual void OnConstruction(int layer) {} + virtual void OnConstruction() {} #ifdef WITH_CXX_GUARDEDALLOC @@ -202,4 +202,5 @@ inline bool operator < ( const RAS_IPolyMaterial & lhs, const RAS_IPolyMaterial return lhs.Less(rhs); } -#endif /* __RAS_IPOLYGONMATERIAL_H__ */ +#endif //__RAS_IPOLYGONMATERIAL_H__ + diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h index e6948025999..91e450ae265 100644 --- a/source/gameengine/Rasterizer/RAS_IRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h @@ -32,8 +32,8 @@ #ifndef __RAS_IRASTERIZER_H__ #define __RAS_IRASTERIZER_H__ -#ifdef _MSC_VER -# pragma warning (disable:4786) +#if defined(WIN32) && !defined(FREE_WINDOWS) +#pragma warning (disable:4786) #endif #include "STR_HashedString.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) }; @@ -423,4 +423,6 @@ public: #endif }; -#endif /* __RAS_IRASTERIZER_H__ */ +#endif //__RAS_IRASTERIZER_H__ + + diff --git a/source/gameengine/Rasterizer/RAS_IRenderTools.h b/source/gameengine/Rasterizer/RAS_IRenderTools.h index bccda634222..ca6f20b71ad 100644 --- a/source/gameengine/Rasterizer/RAS_IRenderTools.h +++ b/source/gameengine/Rasterizer/RAS_IRenderTools.h @@ -208,4 +208,7 @@ public: #endif }; -#endif /* __RAS_IRENDERTOOLS_H__ */ +#endif //__RAS_IRENDERTOOLS_H__ + + + diff --git a/source/gameengine/Rasterizer/RAS_LightObject.h b/source/gameengine/Rasterizer/RAS_LightObject.h index 79818def5f0..ddf360683cd 100644 --- a/source/gameengine/Rasterizer/RAS_LightObject.h +++ b/source/gameengine/Rasterizer/RAS_LightObject.h @@ -64,4 +64,5 @@ struct RAS_LightObject bool m_nospecular; }; -#endif /* __RAS_LIGHTOBJECT_H__ */ +#endif //__RAS_LIGHTOBJECT_H__ + diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp index 9fb47117f1d..6f8cc0e79b8 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp @@ -32,8 +32,8 @@ #include "RAS_MaterialBucket.h" -#ifdef _MSC_VER -# pragma warning (disable:4786) +#if defined(WIN32) && !defined(FREE_WINDOWS) +#pragma warning (disable:4786) #endif #ifdef WIN32 @@ -47,6 +47,7 @@ #include "RAS_MeshObject.h" #include "RAS_Deformer.h" // __NLA + /* mesh slot */ RAS_MeshSlot::RAS_MeshSlot() : SG_QList() @@ -73,7 +74,7 @@ RAS_MeshSlot::~RAS_MeshSlot() #ifdef USE_SPLIT Split(true); - while (m_joinedSlots.size()) + while(m_joinedSlots.size()) m_joinedSlots.front()->Split(true); #endif @@ -147,7 +148,7 @@ void RAS_MeshSlot::begin(RAS_MeshSlot::iterator& it) int startvertex, endvertex; int startindex, endindex; - it.array = m_displayArrays.empty() ? NULL : m_displayArrays[m_startarray]; + it.array = (m_displayArrays.size() > 0)? m_displayArrays[m_startarray]: NULL; if (it.array == NULL || it.array->m_index.size() == 0 || it.array->m_vertex.size() == 0) { it.array = NULL; @@ -368,7 +369,7 @@ bool RAS_MeshSlot::Join(RAS_MeshSlot *target, MT_Scalar distance) size_t i; // verify if we can join - if (m_joinSlot || (m_joinedSlots.empty() == false) || target->m_joinSlot) + if (m_joinSlot || m_joinedSlots.size() || target->m_joinSlot) return false; if (!Equals(target)) @@ -393,7 +394,7 @@ bool RAS_MeshSlot::Join(RAS_MeshSlot *target, MT_Scalar distance) target->m_joinedSlots.push_back(this); MT_Matrix4x4 ntransform = m_joinInvTransform.transposed(); - ntransform[0][3] = ntransform[1][3] = ntransform[2][3] = 0.0f; + ntransform[0][3]= ntransform[1][3]= ntransform[2][3]= 0.0f; for (begin(mit); !end(mit); next(mit)) for (i=mit.startvertex; i<mit.endvertex; i++) @@ -461,7 +462,7 @@ bool RAS_MeshSlot::Split(bool force) abort(); } - if (target->m_displayArrays.empty() == false) { + if (target->m_displayArrays.size()) { target->m_endvertex = target->m_displayArrays.back()->m_vertex.size(); target->m_endindex = target->m_displayArrays.back()->m_index.size(); } @@ -471,7 +472,7 @@ bool RAS_MeshSlot::Split(bool force) } MT_Matrix4x4 ntransform = m_joinInvTransform.inverse().transposed(); - ntransform[0][3] = ntransform[1][3] = ntransform[2][3] = 0.0f; + ntransform[0][3]= ntransform[1][3]= ntransform[2][3]= 0.0f; for (begin(mit); !end(mit); next(mit)) for (i=mit.startvertex; i<mit.endvertex; i++) @@ -605,7 +606,9 @@ 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,10 +651,6 @@ 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); - rendertools->PopMatrix(); } diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.h b/source/gameengine/Rasterizer/RAS_MaterialBucket.h index 4c72f128817..295f2510313 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.h +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.h @@ -189,8 +189,6 @@ class RAS_MeshMaterial public: RAS_MeshSlot *m_baseslot; class RAS_MaterialBucket *m_bucket; - - /* the KX_GameObject is used as a key here */ CTR_Map<CTR_HashedPtr,RAS_MeshSlot*> m_slots; @@ -256,4 +254,4 @@ private: #endif }; -#endif /* __RAS_MATERIAL_BUCKET */ +#endif //__RAS_MATERIAL_BUCKET diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp index 2ccb9453b3d..1bcf7cadde0 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; @@ -584,7 +583,7 @@ void RAS_MeshObject::CheckWeightCache(Object* obj) if (!m_mesh->key) return; - for (kbindex = 0, kb = (KeyBlock *)m_mesh->key->block.first; kb; kb = kb->next, kbindex++) + for (kbindex=0, kb= (KeyBlock*)m_mesh->key->block.first; kb; kb= (KeyBlock*)kb->next, kbindex++) { // first check the cases where the weight must be cleared if (kb->vgroup[0] == 0 || @@ -608,7 +607,7 @@ void RAS_MeshObject::CheckWeightCache(Object* obj) weights= (float*)MEM_mallocN(totvert*sizeof(float), "weights"); for (i=0; i < totvert; i++, dv++) { - weights[i] = defvert_find_weight(dv, defindex); + weights[i]= defvert_find_weight(dv, defindex); } kb->weights = weights; diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h index 281eae8734a..eb5894448f9 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.h +++ b/source/gameengine/Rasterizer/RAS_MeshObject.h @@ -32,9 +32,9 @@ #ifndef __RAS_MESHOBJECT_H__ #define __RAS_MESHOBJECT_H__ -#ifdef _MSC_VER - /* disable the STL warnings ("debug information length > 255") */ -# pragma warning (disable:4786) +#if defined(WIN32) && !defined(FREE_WINDOWS) +// disable the STL warnings ("debug information length > 255") +#pragma warning (disable:4786) #endif #include <vector> @@ -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, @@ -177,4 +176,5 @@ public: #endif }; -#endif /* __RAS_MESHOBJECT_H__ */ +#endif //__RAS_MESHOBJECT_H__ + diff --git a/source/gameengine/Rasterizer/RAS_ObjectColor.h b/source/gameengine/Rasterizer/RAS_ObjectColor.h index 77feffccffc..f8fbe69e97b 100644 --- a/source/gameengine/Rasterizer/RAS_ObjectColor.h +++ b/source/gameengine/Rasterizer/RAS_ObjectColor.h @@ -38,4 +38,5 @@ struct RAS_ObjectColor { float m_blue; }; -#endif /* __RAS_OBJECTCOLOR_H__ */ +#endif //__RAS_OBJECTCOLOR_H__ + diff --git a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Erosion2DFilter.h b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Erosion2DFilter.h index eaefd5c13fa..6319be6ce4a 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Erosion2DFilter.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Erosion2DFilter.h @@ -32,7 +32,7 @@ #ifndef __RAS_EROSION2DFILTER_H__ #define __RAS_EROSION2DFILTER_H__ -const char * ErosionFragmentShader = STRINGIFY( +const char * ErosionFragmentShader=STRINGIFY( uniform sampler2D bgl_RenderedTexture; uniform vec2 bgl_TextureCoordinateOffset[9]; 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_GLExtensionManager.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp index 665053984e6..53a6358c31a 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp @@ -33,6 +33,7 @@ #include <iostream> #include "RAS_GLExtensionManager.h" +#include "GPU_extensions.h" namespace bgl { @@ -52,14 +53,12 @@ namespace bgl std::cout << "Detected GL_ARB_texture_cube_map" << std::endl; if (GLEW_ARB_multitexture) std::cout << "Detected GL_ARB_multitexture" << std::endl; - if (GLEW_ARB_shader_objects) - std::cout << "Detected GL_ARB_shader_objects" << std::endl; - if (GLEW_ARB_vertex_shader) - std::cout << "Detected GL_ARB_vertex_shader" << std::endl; - if (GLEW_ARB_fragment_shader) - std::cout << "Detected GL_ARB_fragment_shader" << std::endl; - if (GLEW_ARB_vertex_program) - std::cout << "Detected GL_ARB_vertex_program" << std::endl; + if (GPU_EXT_GLSL_ENABLED) + std::cout << "Detected GLSL shader support" << std::endl; + if (GPU_EXT_GLSL_FRAGMENT_ENABLED) + std::cout << "Detected GLSL fragment shader support" << std::endl; + if (GPU_EXT_GLSL_VERTEX_ENABLED) + std::cout << "Detected GLSL vertex shader support" << std::endl; if (GLEW_ARB_depth_texture) std::cout << "Detected GL_ARB_depth_texture" << std::endl; if (GLEW_EXT_separate_specular_color) diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h index 1b4d3219335..4c3b69d4d77 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h @@ -32,7 +32,7 @@ #ifndef __RAS_GLEXTENSIONMANAGER_H__ #define __RAS_GLEXTENSIONMANAGER_H__ -#include "GL/glew.h" +#include "GPU_compatibility.h" /** Note: this used to have a lot more code, but now extension handling * is done by GLEW, so it does mostly debug stuff */ 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..4c8d94b11d4 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp @@ -4,13 +4,18 @@ // #include <iostream> +#ifdef GLES +#include <GLES2/gl2.h> +#endif + #include "RAS_ListRasterizer.h" #ifdef WIN32 #include <windows.h> #endif // WIN32 -#include "GL/glew.h" +#define GPU_MANGLE_DEPRECATED 0 +#include "GPU_compatibility.h" #include "RAS_MaterialBucket.h" #include "RAS_TexVert.h" @@ -106,13 +111,14 @@ 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.")) +#include REAL_GL_MODE + if (!strcmp((const char*)glGetString(GL_VENDOR), "ATI Technologies Inc.")) mATI = true; +#include FAKE_GL_MODE } RAS_ListRasterizer::~RAS_ListRasterizer() @@ -124,7 +130,7 @@ void RAS_ListRasterizer::RemoveListSlot(RAS_ListSlot* list) { if (list->m_flag & LIST_DERIVEDMESH) { RAS_DerivedMeshLists::iterator it = mDerivedMeshLists.begin(); - while (it != mDerivedMeshLists.end()) { + while(it != mDerivedMeshLists.end()) { RAS_ListSlots *slots = it->second; if (slots->size() > list->m_matnr && slots->at(list->m_matnr) == list) { (*slots)[list->m_matnr] = NULL; @@ -145,7 +151,7 @@ void RAS_ListRasterizer::RemoveListSlot(RAS_ListSlot* list) } } else { RAS_ArrayLists::iterator it = mArrayLists.begin(); - while (it != mArrayLists.end()) { + while(it != mArrayLists.end()) { if (it->second == list) { mArrayLists.erase(it); break; @@ -238,11 +244,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 +270,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 +280,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..42274767ecc 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -33,16 +33,20 @@ #include <math.h> #include <stdlib.h> + #include "RAS_OpenGLRasterizer.h" -#include "GL/glew.h" - #include "RAS_Rect.h" #include "RAS_TexVert.h" #include "RAS_MeshObject.h" #include "MT_CmMatrix4x4.h" #include "RAS_IRenderTools.h" // rendering text +#include "RAS_StorageIM.h" +#include "RAS_StorageVA.h" +#include "RAS_StorageVBO.h" + +#include "GPU_compatibility.h" #include "GPU_draw.h" #include "GPU_material.h" #include "GPU_extensions.h" @@ -52,10 +56,7 @@ #include "DNA_material_types.h" #include "DNA_scene_types.h" -extern "C"{ - #include "BLI_utildefines.h" - #include "BKE_DerivedMesh.h" -} +#include "BKE_DerivedMesh.h" #ifndef M_PI #define M_PI 3.14159265358979323846 @@ -74,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), @@ -93,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(); @@ -107,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; + } } @@ -115,38 +135,48 @@ 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(); - m_ambr = 0.0f; m_ambg = 0.0f; m_ambb = 0.0f; - +#include REAL_GL_MODE glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* set default blend function */ + //m_last_alphablend = GPU_BLEND_SOLID; GPU_set_material_alpha_blend(GPU_BLEND_SOLID); glFrontFace(GL_CCW); m_last_frontface = true; - +#include FAKE_GL_MODE m_redback = 0.4375; m_greenback = 0.4375; m_blueback = 0.4375; m_alphaback = 0.0; - glClearColor(m_redback,m_greenback,m_blueback,m_alphaback); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + gpuSetClearColor(m_redback,m_greenback,m_blueback,m_alphaback); + gpuClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glShadeModel(GL_SMOOTH); - return true; + storage_init = m_storage->Init(); + + return true && storage_init; } @@ -161,7 +191,7 @@ void RAS_OpenGLRasterizer::SetAmbientColor(float red, float green, float blue) void RAS_OpenGLRasterizer::SetAmbient(float factor) { float ambient[] = { m_ambr*factor, m_ambg*factor, m_ambb*factor, 1.0f }; - glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient); + gpuLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient); } @@ -242,10 +272,10 @@ void RAS_OpenGLRasterizer::DisplayFog() glFogf(GL_FOG_DENSITY, 0.1f); glFogf(GL_FOG_START, m_fogstart); glFogf(GL_FOG_END, m_fogstart + m_fogdist); - params[0] = m_fogr; - params[1] = m_fogg; - params[2] = m_fogb; - params[3] = 0.0; + params[0]= m_fogr; + params[1]= m_fogg; + params[2]= m_fogb; + params[3]= 0.0; glFogfv(GL_FOG_COLOR, params); glEnable(GL_FOG); } @@ -267,21 +297,25 @@ bool RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat) void RAS_OpenGLRasterizer::Exit() { + m_storage->Exit(); +#include REAL_GL_MODE glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); - glClearDepth(1.0); + /*glClearDepth(1.0); */ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glClearColor(m_redback, m_greenback, m_blueback, m_alphaback); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + gpuSetClearColor(m_redback, m_greenback, m_blueback, m_alphaback); + gpuClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDepthMask (GL_TRUE); glDepthFunc(GL_LEQUAL); - glBlendFunc(GL_ONE, GL_ZERO); - + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* reset blender default */ +#include FAKE_GL_MODE + glAlphaFunc(GL_GREATER, 0.5f); /* reset blender default */ + glDisable(GL_POLYGON_STIPPLE); - glDisable(GL_LIGHTING); + gpuDisableLighting(); if (GLEW_EXT_separate_specular_color || GLEW_VERSION_1_2) - glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR); + gpuLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR); EndFrame(); } @@ -289,9 +323,10 @@ 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 +#include REAL_GL_MODE if (m_drawingmode < KX_SOLID) { glDisable (GL_CULL_FACE); @@ -305,12 +340,13 @@ bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time) glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); + //m_last_alphablend = GPU_BLEND_SOLID; GPU_set_material_alpha_blend(GPU_BLEND_SOLID); glFrontFace(GL_CCW); m_last_frontface = true; - +#include FAKE_GL_MODE glShadeModel(GL_SMOOTH); glEnable(GL_MULTISAMPLE_ARB); @@ -324,10 +360,14 @@ bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time) void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode) { +#include REAL_GL_MODE m_drawingmode = drawingmode; if (m_drawingmode == KX_WIREFRAME) glDisable(GL_CULL_FACE); + + m_storage->SetDrawingMode(drawingmode); +#include FAKE_GL_MODE } int RAS_OpenGLRasterizer::GetDrawingMode() @@ -362,39 +402,39 @@ void RAS_OpenGLRasterizer::ClearCachingInfo(void) void RAS_OpenGLRasterizer::FlushDebugShapes() { - if (m_debugShapes.empty()) + if (!m_debugShapes.size()) return; // DrawDebugLines GLboolean light, tex; - light= glIsEnabled(GL_LIGHTING); + light= gpuIsLightingEnabled(); tex= glIsEnabled(GL_TEXTURE_2D); - if (light) glDisable(GL_LIGHTING); + if (light) gpuDisableLighting(); if (tex) glDisable(GL_TEXTURE_2D); //draw lines - glBegin(GL_LINES); + gpuBegin(GL_LINES); for (unsigned int i=0;i<m_debugShapes.size();i++) { if (m_debugShapes[i].m_type != OglDebugShape::LINE) continue; - glColor4f(m_debugShapes[i].m_color[0],m_debugShapes[i].m_color[1],m_debugShapes[i].m_color[2],1.f); + gpuColor4f(m_debugShapes[i].m_color[0],m_debugShapes[i].m_color[1],m_debugShapes[i].m_color[2],1.f); const MT_Scalar* fromPtr = &m_debugShapes[i].m_pos.x(); const MT_Scalar* toPtr= &m_debugShapes[i].m_param.x(); - glVertex3dv(fromPtr); - glVertex3dv(toPtr); + gpuVertex3dv(fromPtr); + gpuVertex3dv(toPtr); } - glEnd(); + gpuEnd(); //draw circles for (unsigned int i=0;i<m_debugShapes.size();i++) { if (m_debugShapes[i].m_type != OglDebugShape::CIRCLE) continue; - glBegin(GL_LINE_LOOP); - glColor4f(m_debugShapes[i].m_color[0],m_debugShapes[i].m_color[1],m_debugShapes[i].m_color[2],1.f); + gpuBegin(GL_LINE_LOOP); + gpuColor4f(m_debugShapes[i].m_color[0],m_debugShapes[i].m_color[1],m_debugShapes[i].m_color[2],1.f); static const MT_Vector3 worldUp(0.0, 0.0, 1.0); MT_Vector3 norm = m_debugShapes[i].m_param; @@ -421,12 +461,12 @@ void RAS_OpenGLRasterizer::FlushDebugShapes() pos = pos*tr; pos += m_debugShapes[i].m_pos; const MT_Scalar* posPtr = &pos.x(); - glVertex3dv(posPtr); + gpuVertex3dv(posPtr); } - glEnd(); + gpuEnd(); } - if (light) glEnable(GL_LIGHTING); + if (light) gpuEnableLighting(); if (tex) glEnable(GL_TEXTURE_2D); m_debugShapes.clear(); @@ -450,7 +490,8 @@ void RAS_OpenGLRasterizer::SetRenderArea() switch (m_stereomode) { case RAS_STEREO_ABOVEBELOW: - switch (m_curreye) { + switch(m_curreye) + { case RAS_STEREO_LEFTEYE: // upper half of window area.SetLeft(0); @@ -621,7 +662,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives_3DText(RAS_MeshSlot& ms, // handle object color if (obcolor) { glDisableClientState(GL_COLOR_ARRAY); - glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); + gpuCurrentColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); } else glEnableClientState(GL_COLOR_ARRAY); @@ -634,18 +675,18 @@ void RAS_OpenGLRasterizer::IndexPrimitives_3DText(RAS_MeshSlot& ms, if (it.array->m_type == RAS_DisplayArray::LINE) { // line drawing, no text - glBegin(GL_LINES); + gpuBegin(GL_LINES); for (i=0; i<it.totindex; i+=2) { vertex = &it.vertex[it.index[i]]; - glVertex3fv(vertex->getXYZ()); + gpuVertex3fv(vertex->getXYZ()); vertex = &it.vertex[it.index[i+1]]; - glVertex3fv(vertex->getXYZ()); + gpuVertex3fv(vertex->getXYZ()); } - glEnd(); + gpuEnd(); } else { // triangle and quad text drawing @@ -664,9 +705,9 @@ void RAS_OpenGLRasterizer::IndexPrimitives_3DText(RAS_MeshSlot& ms, // find the right opengl attribute glattrib = -1; - if (GLEW_ARB_vertex_program) + if (GPU_EXT_GLSL_VERTEX_ENABLED) 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,278 +749,58 @@ 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); + gpuMatrixCommit(); + 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, ¤t_gpu_attribs, sizeof(GPUVertexAttribs)); - return 1; + gpuMatrixCommit(); + if (ms.m_pDerivedMesh) + m_failsafe_storage->IndexPrimitivesMulti(ms); + else + m_storage->IndexPrimitivesMulti(ms); } -/* -static int CheckTexfaceDM(void *mcol, int index) +void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat) { + gpuMatrixMode(GL_PROJECTION); - // 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; -} -*/ + float matrix[16]; + double *matrixd; + /*test me*/ + matrixd = mat.getPointer(); -static DMDrawOption CheckTexDM(MTFace *tface, int has_mcol, int matnr) -{ + for(int i=0;i<16;i++) + matrix[i]=matrixd[i]; - // index is the original face index, retrieve the polygon - if (matnr == current_blmat_nr && - (tface == NULL || tface->tpage == current_image)) { - // must handle color. - if (current_wireframe) - return DM_DRAW_OPTION_NO_MCOL; - if (current_ms->m_bObjectColor) { - MT_Vector4& rgba = current_ms->m_RGBAcolor; - glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); - // don't use mcol - return DM_DRAW_OPTION_NO_MCOL; - } - if (!has_mcol) { - // we have to set the color from the material - unsigned char rgba[4]; - current_polymat->GetMaterialRGBAColor(rgba); - glColor4ubv((const GLubyte *)rgba); - return DM_DRAW_OPTION_NO_MCOL; - } - return DM_DRAW_OPTION_NORMAL; - } - return DM_DRAW_OPTION_SKIP; -} - -void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi) -{ - bool obcolor = ms.m_bObjectColor; - bool wireframe = m_drawingmode <= KX_WIREFRAME; - MT_Vector4& rgba = ms.m_RGBAcolor; - RAS_MeshSlot::iterator it; - - if (ms.m_pDerivedMesh) { - // mesh data is in derived mesh, - current_bucket = ms.m_bucket; - current_polymat = current_bucket->GetPolyMaterial(); - current_ms = &ms; - current_mesh = ms.m_mesh; - current_wireframe = wireframe; - // MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL); /* UNUSED */ - - // handle two-side - if (current_polymat->GetDrawingMode() & RAS_IRasterizer::KX_BACKCULL) - this->SetCullFace(true); - else - this->SetCullFace(false); - - if (current_polymat->GetFlag() & RAS_BLENDERGLSL) { - // GetMaterialIndex return the original mface material index, - // increment by 1 to match what derived mesh is doing - current_blmat_nr = current_polymat->GetMaterialIndex()+1; - // For GLSL we need to retrieve the GPU material attribute - Material* blmat = current_polymat->GetBlenderMaterial(); - Scene* blscene = current_polymat->GetBlenderScene(); - if (!wireframe && blscene && blmat) - GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat), ¤t_gpu_attribs); - else - memset(¤t_gpu_attribs, 0, sizeof(current_gpu_attribs)); - // DM draw can mess up blending mode, restore at the end - int current_blend_mode = GPU_get_material_alpha_blend(); - ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM); - GPU_set_material_alpha_blend(current_blend_mode); - } - else { - //ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol); - current_blmat_nr = current_polymat->GetMaterialIndex(); - current_image = current_polymat->GetBlenderImage(); - ms.m_pDerivedMesh->drawFacesTex(ms.m_pDerivedMesh, CheckTexDM, NULL, NULL); - } - return; - } - // iterate over display arrays, each containing an index + vertex array - for (ms.begin(it); !ms.end(it); ms.next(it)) { - RAS_TexVert *vertex; - size_t i, j, numvert; - - numvert = it.array->m_type; - - if (it.array->m_type == RAS_DisplayArray::LINE) { - // line drawing - glBegin(GL_LINES); - - for (i=0; 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(); - } - } -} - -void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat) -{ - glMatrixMode(GL_PROJECTION); - double* matrix = &mat(0, 0); - glLoadMatrixd(matrix); + gpuLoadMatrix(matrix); + gpuMatrixCommit(); m_camortho = (mat(3, 3) != 0.0); + + gpuMatrixMode(GL_MODELVIEW); } void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat) { - glMatrixMode(GL_PROJECTION); - double matrix[16]; + gpuMatrixMode(GL_PROJECTION); + + float matrix[16]; /* Get into argument. Looks a bit dodgy, but it's ok. */ mat.getValue(matrix); /* Internally, MT_Matrix4x4 uses doubles (MT_Scalar). */ - glLoadMatrixd(matrix); + gpuLoadMatrix(matrix); + gpuMatrixCommit(); m_camortho= (mat[3][3] != 0.0); + + gpuMatrixMode(GL_MODELVIEW); } MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix( @@ -993,7 +814,6 @@ MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix( bool ) { MT_Matrix4x4 result; - double mat[16]; // correction for stereo if (Stereo()) @@ -1009,7 +829,8 @@ MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix( near_div_focallength = frustnear / m_focallength; offset = 0.5f * m_eyeseparation * near_div_focallength; - switch (m_curreye) { + switch(m_curreye) + { case RAS_STEREO_LEFTEYE: left += offset; right += offset; @@ -1021,13 +842,10 @@ MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix( } // leave bottom and top untouched } - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glFrustum(left, right, bottom, top, frustnear, frustfar); - - glGetDoublev(GL_PROJECTION_MATRIX, mat); - result.setValue(mat); + + float tm [16]; + mat4_frustum_set(reinterpret_cast<float (*)[4]>(tm), left, right, bottom, top, frustnear, frustfar); + result.setValue(tm); return result; } @@ -1041,15 +859,10 @@ MT_Matrix4x4 RAS_OpenGLRasterizer::GetOrthoMatrix( float frustfar ) { MT_Matrix4x4 result; - double mat[16]; - // stereo is meaning less for orthographic, disable it - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(left, right, bottom, top, frustnear, frustfar); - - glGetDoublev(GL_PROJECTION_MATRIX, mat); - result.setValue(mat); + float tm [16]; + mat4_ortho_set(reinterpret_cast<float (*)[4]>(tm), left, right, bottom, top, frustnear, frustfar); + result.setValue(tm); return result; } @@ -1079,7 +892,8 @@ void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, // vector between eyes eyeline = viewDir.cross(viewupVec); - switch (m_curreye) { + switch(m_curreye) + { case RAS_STEREO_LEFTEYE: { // translate to left by half the eye distance @@ -1107,9 +921,23 @@ void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, // note: getValue gives back column major as needed by OpenGL MT_Scalar glviewmat[16]; m_viewmatrix.getValue(glviewmat); + float tm[16]; + for(int i=0;i<16;i++)tm[i]=glviewmat[i]; + + //gpuMatrixMode(GL_MODELVIEW); + + + + + //gpuMatrixMode(GL_PROJECTION); + //gpuGetMatrix(GL_PROJECTION_MATRIX, pm); + + gpuMatrixMode(GL_MODELVIEW); + //gpuLoadMatrix(pm); + gpuLoadMatrix(tm); + gpuMatrixCommit(); + //gpuMultMatrix(tm); - glMatrixMode(GL_MODELVIEW); - glLoadMatrixd(glviewmat); m_campos = pos; } @@ -1126,10 +954,12 @@ bool RAS_OpenGLRasterizer::GetCameraOrtho() void RAS_OpenGLRasterizer::SetCullFace(bool enable) { +#include REAL_GL_MODE if (enable) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); +#include FAKE_GL_MODE } void RAS_OpenGLRasterizer::SetLines(bool enable) @@ -1146,7 +976,7 @@ void RAS_OpenGLRasterizer::SetSpecularity(float specX, float specval) { GLfloat mat_specular[] = {specX, specY, specZ, specval}; - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular); + gpuMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular); } @@ -1154,7 +984,7 @@ void RAS_OpenGLRasterizer::SetSpecularity(float specX, void RAS_OpenGLRasterizer::SetShinyness(float shiny) { GLfloat mat_shininess[] = { shiny }; - glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess); + gpuMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess); } @@ -1162,13 +992,13 @@ void RAS_OpenGLRasterizer::SetShinyness(float shiny) void RAS_OpenGLRasterizer::SetDiffuse(float difX,float difY,float difZ,float diffuse) { GLfloat mat_diffuse [] = {difX, difY,difZ, diffuse}; - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse); + gpuMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse); } void RAS_OpenGLRasterizer::SetEmissive(float eX, float eY, float eZ, float e) { GLfloat mat_emit [] = {eX,eY,eZ,e}; - glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat_emit); + gpuMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat_emit); } @@ -1207,36 +1037,8 @@ void RAS_OpenGLRasterizer::DisableMotionBlur() void RAS_OpenGLRasterizer::SetAlphaBlend(int alphablend) { GPU_set_material_alpha_blend(alphablend); -/* - if (alphablend == m_last_alphablend) - return; - - if (alphablend == GPU_BLEND_SOLID) { - glDisable(GL_BLEND); - glDisable(GL_ALPHA_TEST); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - else if (alphablend == GPU_BLEND_ADD) { - glBlendFunc(GL_ONE, GL_ONE); - glEnable(GL_BLEND); - glDisable(GL_ALPHA_TEST); - } - else if (alphablend == GPU_BLEND_ALPHA) { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0.0f); - } - else if (alphablend == GPU_BLEND_CLIP) { - glDisable(GL_BLEND); - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0.5f); - } - - m_last_alphablend = alphablend; -*/ } - +#include REAL_GL_MODE void RAS_OpenGLRasterizer::SetFrontFace(bool ccw) { if (m_last_frontface == ccw) diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h index 88bb0be531b..1d64c4353e9 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h @@ -32,8 +32,8 @@ #ifndef __RAS_OPENGLRASTERIZER_H__ #define __RAS_OPENGLRASTERIZER_H__ -#ifdef _MSC_VER -# pragma warning (disable:4786) +#if defined(WIN32) && !defined(FREE_WINDOWS) +#pragma warning (disable:4786) #endif #include "MT_CmMatrix4x4.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( @@ -322,4 +326,6 @@ public: #endif }; -#endif /* __RAS_OPENGLRASTERIZER_H__ */ +#endif //__RAS_OPENGLRASTERIZER_H__ + + 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..80a1c4ddb5b --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp @@ -0,0 +1,408 @@ +/* + * ***** 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 "GPU_compatibility.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; + + for (unit = 0; unit < *m_texco_num; unit++) { + switch(m_texco[unit]) { + case RAS_IRasterizer::RAS_TEXCO_ORCO: + case RAS_IRasterizer::RAS_TEXCO_GLOB: + gpuMultiTexCoord3fv(unit, tv.getXYZ()); + break; + case RAS_IRasterizer::RAS_TEXCO_UV: + gpuMultiTexCoord2fv(unit, tv.getUV(unit)); + break; + case RAS_IRasterizer::RAS_TEXCO_NORM: + gpuMultiTexCoord3fv(unit, tv.getNormal()); + break; + case RAS_IRasterizer::RAS_TEXTANGENT: + gpuMultiTexCoord4fv(unit, tv.getTangent()); + break; + default: + break; + } + } + + if (*m_attrib_num > 0) { + int uv = 0; + + int index_f = 0; + int index_ub = 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: + gpuVertexAttrib3fv(index_f++, tv.getXYZ()); + break; + case RAS_IRasterizer::RAS_TEXCO_UV: + gpuVertexAttrib2fv(index_f++, tv.getUV(uv++)); + break; + case RAS_IRasterizer::RAS_TEXCO_NORM: + gpuVertexAttrib3fv(index_f++, tv.getNormal()); + break; + case RAS_IRasterizer::RAS_TEXTANGENT: + gpuVertexAttrib4fv(index_f++, tv.getTangent()); + break; + case RAS_IRasterizer::RAS_TEXCO_VCOL: + gpuVertexAttrib4ubv(index_ub++, tv.getRGBA()); + break; + default: + break; + } + } + } +} + +void RAS_StorageIM::SetCullFace(bool enable) +{ + if (enable) + glEnable(GL_CULL_FACE); + else + glDisable(GL_CULL_FACE); +} + +static bool current_wireframe; +static RAS_MaterialBucket *current_bucket; +static RAS_IPolyMaterial *current_polymat; +static RAS_MeshSlot *current_ms; +static RAS_MeshObject *current_mesh; +static int current_blmat_nr; +static GPUVertexAttribs current_gpu_attribs; +static Image *current_image; +static int CheckMaterialDM(int matnr, void *attribs) +{ + // only draw the current material + if (matnr != current_blmat_nr) + return 0; + GPUVertexAttribs *gattribs = (GPUVertexAttribs *)attribs; + if (gattribs) + memcpy(gattribs, ¤t_gpu_attribs, sizeof(GPUVertexAttribs)); + return 1; +} + +/* +static int CheckTexfaceDM(void *mcol, int index) +{ + + // index is the original face index, retrieve the polygon + RAS_Polygon* polygon = (index >= 0 && index < current_mesh->NumPolygons()) ? + current_mesh->GetPolygon(index) : NULL; + if (polygon && polygon->GetMaterial() == current_bucket) { + // must handle color. + if (current_wireframe) + return 2; + if (current_ms->m_bObjectColor) { + MT_Vector4& rgba = current_ms->m_RGBAcolor; + gpuCurrentColor4d(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); + gpuCurrentColor4ubv((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; + } + else if (current_ms->m_bObjectColor) { + MT_Vector4& rgba = current_ms->m_RGBAcolor; + gpuColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); + // don't use mcol + + return DM_DRAW_OPTION_NO_MCOL; + } + else if (!has_mcol) { + // we have to set the color from the material + unsigned char rgba[4]; + current_polymat->GetMaterialRGBAColor(rgba); + gpuColor4ubv((const GLubyte *)rgba); + + return DM_DRAW_OPTION_NO_MCOL; + } + else { + return DM_DRAW_OPTION_NORMALLY; + } + } + else { + return DM_DRAW_OPTION_SKIP; + } +} + +void RAS_StorageIM::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi) +{ + bool obcolor = ms.m_bObjectColor; + bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME; + MT_Vector4& rgba = ms.m_RGBAcolor; + RAS_MeshSlot::iterator it; + + if (ms.m_pDerivedMesh) { + // mesh data is in derived mesh, + current_bucket = ms.m_bucket; + current_polymat = current_bucket->GetPolyMaterial(); + current_ms = &ms; + current_mesh = ms.m_mesh; + current_wireframe = wireframe; + // MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL); /* UNUSED */ + + // handle two-side + if (current_polymat->GetDrawingMode() & RAS_IRasterizer::KX_BACKCULL) + this->SetCullFace(true); + else + this->SetCullFace(false); + + if (current_polymat->GetFlag() & RAS_BLENDERGLSL) { + // GetMaterialIndex return the original mface material index, + // increment by 1 to match what derived mesh is doing + current_blmat_nr = current_polymat->GetMaterialIndex()+1; + // For GLSL we need to retrieve the GPU material attribute + Material* blmat = current_polymat->GetBlenderMaterial(); + Scene* blscene = current_polymat->GetBlenderScene(); + if (!wireframe && blscene && blmat) + GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat), ¤t_gpu_attribs); + else + memset(¤t_gpu_attribs, 0, sizeof(current_gpu_attribs)); + // DM draw can mess up blending mode, restore at the end + int current_blend_mode = GPU_get_material_alpha_blend(); + ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM); + GPU_set_material_alpha_blend(current_blend_mode); + } else { + //ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol); + current_blmat_nr = current_polymat->GetMaterialIndex(); + current_image = current_polymat->GetBlenderImage(); + ms.m_pDerivedMesh->drawFacesTex(ms.m_pDerivedMesh, CheckTexDM, NULL, NULL); + } + return; + } + + { + static const GLenum tex[16] = { + GL_TEXTURE0, GL_TEXTURE1, GL_TEXTURE2, GL_TEXTURE3, + GL_TEXTURE4, GL_TEXTURE5, GL_TEXTURE6, GL_TEXTURE7, + GL_TEXTURE8, GL_TEXTURE9, GL_TEXTURE10, GL_TEXTURE11, + GL_TEXTURE12, GL_TEXTURE13, GL_TEXTURE14, GL_TEXTURE15, + }; + + GLint texSize[16]; + + GLenum attrib_f[16]; + GLint attribSize_f[16]; + GLint count_f = 0; + GLenum attrib_ub[16]; + GLint attribSize_ub[16]; + GLint count_ub = 0; + + int unit; + + GPU_ASSERT(*m_texco_num <= 16); + GPU_ASSERT(*m_attrib_num <= 16); + + gpuImmediateElementSizes(3, 3, 4); + + for (unit = 0; unit < *m_texco_num; unit++) { + switch(m_texco[unit]) { + case RAS_IRasterizer::RAS_TEXCO_ORCO: + case RAS_IRasterizer::RAS_TEXCO_GLOB: + texSize[unit] = 3; + break; + case RAS_IRasterizer::RAS_TEXCO_UV: + texSize[unit] = 2; + break; + case RAS_IRasterizer::RAS_TEXCO_NORM: + texSize[unit] = 3; + break; + case RAS_IRasterizer::RAS_TEXTANGENT: + texSize[unit] = 4; + break; + default: + break; + } + } + + gpuImmediateTextureUnitCount(*m_texco_num); + gpuImmediateTexCoordSizes(texSize); + gpuImmediateTextureUnitMap(tex); + + for (unit = 0; unit < *m_attrib_num; unit++) { + switch(m_attrib[unit]) { + case RAS_IRasterizer::RAS_TEXCO_ORCO: + case RAS_IRasterizer::RAS_TEXCO_GLOB: + attrib_f[count_f] = unit; + attribSize_f[count_f] = 3; + count_f++; + break; + case RAS_IRasterizer::RAS_TEXCO_UV: + attrib_f[count_f] = unit; + attribSize_f[count_f] = 2; + count_f++; + break; + case RAS_IRasterizer::RAS_TEXCO_NORM: + attrib_f[count_f] = unit; + attribSize_f[count_f] = 3; + count_f++; + break; + case RAS_IRasterizer::RAS_TEXTANGENT: + attrib_f[count_f] = unit; + attribSize_f[count_f] = 4; + count_f++; + break; + case RAS_IRasterizer::RAS_TEXCO_VCOL: + attrib_ub[count_ub] = unit; + attribSize_ub[count_ub] = 4; + count_ub++; + break; + default: + break; + } + } + + gpuImmediateFloatAttribCount(count_f); + gpuImmediateFloatAttribSizes(attribSize_f); + gpuImmediateFloatAttribIndexMap(attrib_f); + + gpuImmediateUbyteAttribCount(count_ub); + gpuImmediateUbyteAttribSizes(attribSize_ub); + gpuImmediateUbyteAttribIndexMap(attrib_ub); + } + + gpuImmediateLock(); + + // 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 + gpuBegin(GL_LINES); + + for (i = 0; i < it.totindex; i += 2) + { + vertex = &it.vertex[it.index[i]]; + gpuVertex3fv(vertex->getXYZ()); + + vertex = &it.vertex[it.index[i+1]]; + gpuVertex3fv(vertex->getXYZ()); + } + + gpuEnd(); + } + else { + // triangle and quad drawing + if (it.array->m_type == RAS_DisplayArray::TRIANGLE) + gpuBegin(GL_TRIANGLES); + else + gpuBegin(GL_QUADS); + + for (i = 0; i < it.totindex; i += numvert) + { + if (obcolor) + gpuColor4d(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) + gpuColor4ubv((const GLubyte *)(vertex->getRGBA())); + + gpuNormal3fv(vertex->getNormal()); + + if (multi) + TexCoord(*vertex); + else + gpuTexCoord2fv(vertex->getUV(0)); + } + + gpuVertex3fv(vertex->getXYZ()); + } + } + + gpuEnd(); + } + } + + gpuImmediateUnlock(); +} 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..936f9ea0657 --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp @@ -0,0 +1,591 @@ +/* + * ***** 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 ***** + */ + +#ifdef GLES +#include <GLES2/gl2.h> +#endif + +#include "GPU_extensions.h" + +#include "RAS_StorageVA.h" + +#include "GPU_compatibility.h" +#include "GPU_colors.h" +#include "GPU_material.h" +#include "GPU_object.h" +#include "GPU_functions.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() +{ +} + + +#include REAL_GL_MODE +#include <stdio.h> + GLuint programObject = 0; + + +GLuint MobLoadShader(GLenum type, const char *src) +{ + GLuint shader; + GLint compiled; + + shader = glCreateShader (type); + + if (!shader) + return 0; + + glShaderSource(shader, 1, &src, NULL); + glCompileShader (shader); + + glGetShaderiv (shader, GL_COMPILE_STATUS, &compiled); + + if (!compiled) + { + GLint infoLen = 0; + + glGetShaderiv (shader, GL_INFO_LOG_LENGTH, &infoLen); + + if(infoLen > 0) + { + char* log = (char*)malloc(sizeof(char) * infoLen); + + glGetShaderInfoLog(shader, infoLen, NULL, log); + printf ("Error:\n%s\n", log); + + free(log); + } + + glDeleteShader(shader); + return 0; + } + + return shader; +} + + +int MobInit ( void) +{ + + const char vShaderStr[] = + "precision mediump float; \n" + "attribute vec4 vPosition; \n" + "attribute vec4 vNorm; \n" + "varying vec3 pos; \n" + "varying vec3 normv; \n" + "uniform mat4 bProjectionMatrix ; \n" + "uniform mat4 bModelViewMatrix ; \n" + "varying vec3 lightp; \n" + "void main() \n" + "{ \n" + "lightp = vec3(6.0, 6.0, 6.0);" + "vec4 posmodel = bModelViewMatrix * vPosition;\n" + "pos = vec3( posmodel); \n" + "normv = normalize(vec3(bModelViewMatrix *vNorm)); \n" + " gl_Position = bProjectionMatrix * posmodel; \n" + "} \n" + " \n"; + + const char fShaderStr[] = + "precision mediump float; \n" + "varying vec3 pos; \n" + "varying vec3 normv; \n" + "varying vec3 lightp ; \n" + "void main() \n" + "{ \n" + "vec3 diff = pos-lightp; \n" + "float mull = (1000.0*dot(normalize(diff),normv)/sqrt(dot(diff,diff))/dot(diff,diff)); \n" + "if(mull>1.0){mull=1.0;};\n" + //"if(mull<0.0){mull*=-1.0;};\n" + "gl_FragColor = vec4 (vec3(mull), 1.0 ); \n" + "} \n"; + + GLuint vertexShader; + GLuint fragmentShader; + GLint linked; + + vertexShader = MobLoadShader(GL_VERTEX_SHADER, vShaderStr); + fragmentShader = MobLoadShader(GL_FRAGMENT_SHADER, fShaderStr); + + programObject = glCreateProgram(); + + if (programObject == 0) + return 0; + + glAttachShader(programObject, vertexShader); + glAttachShader(programObject, fragmentShader); + + glBindAttribLocation(programObject, 0, "vPosition"); + glBindAttribLocation(programObject, 1, "vNorm"); + + glLinkProgram(programObject); + + glGetProgramiv(programObject, GL_LINK_STATUS, &linked); + + if (!linked) + { + GLint size = 0; + + glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &size); + if (size > 0) + { + char* log = (char*)malloc(sizeof(char) * size); + + glGetProgramInfoLog(programObject, size, NULL, log); + printf("Error:\n%s\n", log); + + free (log); + } + + glDeleteProgram(programObject); + return GL_FALSE; + } + + + + return GL_TRUE; +} + + +#include FAKE_GL_MODE + + +#ifdef GLES + +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; + + GLint posmat; + float mat[16]; + + + 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); + gpuCurrentColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); + } + else { + gpuCurrentColor3x(CPACK_BLACK); + glEnableClientState(GL_COLOR_ARRAY); + } + } + else + gpuCurrentColor3x(CPACK_BLACK); + +#include REAL_GL_MODE + //glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ()); + if(programObject==0) + { + + MobInit(); + //programObject =1; + + glEnable(GL_DEPTH_TEST); + + + } +glFrontFace(GL_CCW); + glDisable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + glClear(GL_DEPTH_BUFFER_BIT); + glEnable(GL_DEPTH_TEST); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +glDepthMask( true ); + glUseProgram (programObject ); + + gpuGetMatrix(GL_MODELVIEW_MATRIX, mat); + posmat = glGetUniformLocation(programObject, "bModelViewMatrix"); + glUniformMatrix4fv(posmat,1,0,mat); + + gpuGetMatrix(GL_PROJECTION_MATRIX, mat); + posmat = glGetUniformLocation(programObject, "bProjectionMatrix"); + glUniformMatrix4fv(posmat,1,0,mat); + + int infoLen; + glGetProgramiv ( programObject, GL_ACTIVE_UNIFORMS, &infoLen ); + + glVertexAttribPointer(0, 3, GL_FLOAT, 0,stride, it.vertex->getXYZ()); + glEnableVertexAttribArray ( 0 ); + glVertexAttribPointer(1, 3, GL_FLOAT, 0,stride, it.vertex->getNormal()); + glEnableVertexAttribArray ( 1 ); + +#include FAKE_GL_MODE + 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 + +#include REAL_GL_MODE + glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index); +#include FAKE_GL_MODE + } + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + if (!wireframe) { + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + } +} + + +#else + +void RAS_StorageVA::IndexPrimitives(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; + + gpuMatrixCommit(); + + 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); + gpuCurrentColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); + use_color_array = false; + } + else { + gpuCurrentColor3x(CPACK_BLACK); + glEnableClientState(GL_COLOR_ARRAY); + use_color_array = true; + } + } + else { + gpuCurrentColor3x(CPACK_BLACK); + } + + 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 (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_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + } +} + + + +#endif + +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); + gpuCurrentColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); + use_color_array = false; + } + else { + gpuCurrentColor3x(CPACK_BLACK); + glEnableClientState(GL_COLOR_ARRAY); + use_color_array = true; + } + } + else { + gpuCurrentColor3x(CPACK_BLACK); + } + + + gpuMatrixCommit(); + + + gpugameobj.gpuVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ()); + gpugameobj.gpuNormalPointer(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 +#include REAL_GL_MODE + // here the actual drawing takes places + glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index); +#include FAKE_GL_MODE + } + + 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 (GPU_EXT_GLSL_VERTEX_ENABLED) { + 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: + gpu_glVertexAttribPointer(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getXYZ()); + break; + case RAS_IRasterizer::RAS_TEXCO_UV: + gpu_glVertexAttribPointer(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV(uv++)); + break; + case RAS_IRasterizer::RAS_TEXCO_NORM: + gpu_glVertexAttribPointer(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal()); + break; + case RAS_IRasterizer::RAS_TEXTANGENT: + gpu_glVertexAttribPointer(unit, 4, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent()); + break; + case RAS_IRasterizer::RAS_TEXCO_VCOL: + gpu_glVertexAttribPointer(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 (GPU_EXT_GLSL_VERTEX_ENABLED) { + 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) gpu_glEnableVertexAttribArray(unit); + else gpu_glDisableVertexAttribArray(unit); + break; + default: + gpu_glDisableVertexAttribArray(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..cc59ce0ae7f --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp @@ -0,0 +1,265 @@ +/* + * ***** 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 "GPU_compatibility.h" +#include REAL_GL_MODE /* GPU_compatibility.h includes intern/gpu_immediate_inline.h which includes fake glew.h. We need to switch to real mode due to glDraw. Should be removed soon.*/ +#include "GPU_extensions.h" + +#include "GPU_object.h" +#include "GPU_functions.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 + gpu_glGenBuffers(1, &this->ibo); + gpu_glGenBuffers(1, &this->vbo_id); + + this->vbo = GPU_EXT_MAPBUFFER_ENABLED ? NULL : 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)); +} + +VBO::~VBO() +{ + gpu_glDeleteBuffers(1, &this->ibo); + gpu_glDeleteBuffers(1, &this->vbo_id); + + delete this->vbo; +} + +void VBO::UpdateData() +{ + unsigned int i, j, k; + + gpu_glBindBuffer(GL_ARRAY_BUFFER, this->vbo_id); + + // Map the buffer or frees previous + GLfloat *vbo_map = (GLfloat*)gpuBufferStartUpdate(GL_ARRAY_BUFFER, this->stride*this->size, vbo, GL_DYNAMIC_DRAW); + // 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); + } + gpuBufferFinishUpdate(GL_ARRAY_BUFFER, this->stride*this->size, vbo, GL_DYNAMIC_DRAW); +} + +void VBO::UpdateIndices() +{ + int space = data->m_index.size() * sizeof(GLushort); + gpu_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->ibo); + + // Upload Data to VBO + gpu_glBufferData(GL_ELEMENT_ARRAY_BUFFER, space, &data->m_index[0], GL_DYNAMIC_DRAW); +} + +void VBO::Draw(int texco_num, RAS_IRasterizer::TexCoGen* texco, int attrib_num, RAS_IRasterizer::TexCoGen* attrib, bool multi) +{ + int unit; + + // Bind buffers + gpu_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->ibo); + gpu_glBindBuffer(GL_ARRAY_BUFFER, this->vbo_id); + + // Vertexes + gpugameobj.gpuVertexPointer(3, GL_FLOAT, this->stride, this->vertex_offset); + + // Normals + gpugameobj.gpuNormalPointer(GL_FLOAT, this->stride, this->normal_offset); + + // Colors + gpugameobj.gpuColorPointer(4, GL_UNSIGNED_BYTE, this->stride, this->color_offset); + + if(GPU_GLTYPE_FIXED_ENABLED) + { + if (multi) + { + for (unit = 0; unit < texco_num; ++unit) + { + gpugameobj.gpuClientActiveTexture(GL_TEXTURE0 + unit); + switch (texco[unit]) + { + case RAS_IRasterizer::RAS_TEXCO_ORCO: + case RAS_IRasterizer::RAS_TEXCO_GLOB: + gpugameobj.gpuTexCoordPointer(3, GL_FLOAT, this->stride, this->vertex_offset); + break; + case RAS_IRasterizer::RAS_TEXCO_UV: + gpugameobj.gpuTexCoordPointer(2, GL_FLOAT, this->stride, (void*)((intptr_t)this->uv_offset+(sizeof(GLfloat)*2*unit))); + break; + case RAS_IRasterizer::RAS_TEXCO_NORM: + gpugameobj.gpuTexCoordPointer(3, GL_FLOAT, this->stride, this->normal_offset); + break; + case RAS_IRasterizer::RAS_TEXTANGENT: + gpugameobj.gpuTexCoordPointer(4, GL_FLOAT, this->stride, this->tangent_offset); + break; + default: + break; + } + } + gpugameobj.gpuClientActiveTexture(GL_TEXTURE0); + } + else //TexFace + { + gpugameobj.gpuClientActiveTexture(GL_TEXTURE0); + gpugameobj.gpuTexCoordPointer(2, GL_FLOAT, this->stride, this->uv_offset); + } + } + + if (GPU_EXT_GLSL_VERTEX_ENABLED) + { + 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: + gpu_glVertexAttribPointer(unit, 3, GL_FLOAT, GL_FALSE, this->stride, this->vertex_offset); + gpu_glEnableVertexAttribArray(unit); + break; + case RAS_IRasterizer::RAS_TEXCO_UV: + gpu_glVertexAttribPointer(unit, 2, GL_FLOAT, GL_FALSE, this->stride, (void*)((intptr_t)this->uv_offset+uv)); + uv += sizeof(GLfloat)*2; + gpu_glEnableVertexAttribArray(unit); + break; + case RAS_IRasterizer::RAS_TEXCO_NORM: + gpu_glVertexAttribPointer(unit, 2, GL_FLOAT, GL_FALSE, stride, this->normal_offset); + gpu_glEnableVertexAttribArray(unit); + break; + case RAS_IRasterizer::RAS_TEXTANGENT: + gpu_glVertexAttribPointer(unit, 4, GL_FLOAT, GL_FALSE, this->stride, this->tangent_offset); + gpu_glEnableVertexAttribArray(unit); + break; + default: + break; + } + } + } + + glDrawElements(this->mode, this->indices, GL_UNSIGNED_SHORT, 0); + + gpugameobj.gpuCleanupAfterDraw(); + + if (GPU_EXT_GLSL_VERTEX_ENABLED) + { + for (int i = 0; i < attrib_num; ++i) + gpu_glDisableVertexAttribArray(i); + } + + gpu_glBindBuffer(GL_ARRAY_BUFFER, 0); + gpu_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 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; + + gpuMatrixCommit(); + + 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..a42a7ee1929 --- /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 "GPU_compatibility.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; +}; + +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; - } -} - diff --git a/source/gameengine/Rasterizer/RAS_Polygon.cpp b/source/gameengine/Rasterizer/RAS_Polygon.cpp index 74544a80efa..a6912c0997d 100644 --- a/source/gameengine/Rasterizer/RAS_Polygon.cpp +++ b/source/gameengine/Rasterizer/RAS_Polygon.cpp @@ -29,8 +29,9 @@ * \ingroup bgerast */ -#ifdef _MSC_VER -# pragma warning (disable:4786) + +#if defined(WIN32) && !defined(FREE_WINDOWS) +#pragma warning (disable:4786) #endif #include "RAS_Polygon.h" @@ -40,7 +41,7 @@ RAS_Polygon::RAS_Polygon(RAS_MaterialBucket* bucket, RAS_DisplayArray *darray, i { m_bucket = bucket; m_darray = darray; - m_offset[0] = m_offset[1] = m_offset[2] = m_offset[3] = 0; + m_offset[0]= m_offset[1]= m_offset[2]= m_offset[3]= 0; m_numvert = numvert; // m_edgecode = 255; diff --git a/source/gameengine/Rasterizer/RAS_Rect.h b/source/gameengine/Rasterizer/RAS_Rect.h index fc99c9159db..cb5f7d47457 100644 --- a/source/gameengine/Rasterizer/RAS_Rect.h +++ b/source/gameengine/Rasterizer/RAS_Rect.h @@ -101,4 +101,5 @@ public: #endif }; -#endif /* __RAS_RECT_H__ */ +#endif // __RAS_RECT_H__ + diff --git a/source/gameengine/Rasterizer/RAS_TexMatrix.h b/source/gameengine/Rasterizer/RAS_TexMatrix.h index a2dd291d016..44ae1b0eb5d 100644 --- a/source/gameengine/Rasterizer/RAS_TexMatrix.h +++ b/source/gameengine/Rasterizer/RAS_TexMatrix.h @@ -39,4 +39,5 @@ void RAS_CalcTexMatrix(RAS_TexVert p[3],MT_Point3& origin,MT_Vector3& udir,MT_Vector3& vdir); -#endif /* __RAS_TEXMATRIX_H__ */ +#endif //__RAS_TEXMATRIX_H__ + diff --git a/source/gameengine/Rasterizer/RAS_TexVert.cpp b/source/gameengine/Rasterizer/RAS_TexVert.cpp index 945644ff3e6..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() @@ -63,10 +65,10 @@ const MT_Point3& RAS_TexVert::xyz() void RAS_TexVert::SetRGBA(const MT_Vector4& rgba) { unsigned char *colp = (unsigned char*) &m_rgba; - colp[0] = (unsigned char) (rgba[0] * 255.0); - colp[1] = (unsigned char) (rgba[1] * 255.0); - colp[2] = (unsigned char) (rgba[2] * 255.0); - colp[3] = (unsigned char) (rgba[3] * 255.0); + colp[0] = (unsigned char) (rgba[0]*255.0f); + colp[1] = (unsigned char) (rgba[1]*255.0f); + colp[2] = (unsigned char) (rgba[2]*255.0f); + colp[3] = (unsigned char) (rgba[3]*255.0f); } @@ -75,32 +77,16 @@ void RAS_TexVert::SetXYZ(const MT_Point3& xyz) xyz.getValue(m_localxyz); } -void RAS_TexVert::SetXYZ(const float xyz[3]) -{ - m_localxyz[0] = xyz[0]; m_localxyz[1] = xyz[1]; m_localxyz[2] = xyz[2]; -} - -void RAS_TexVert::SetUV1(const MT_Point2& uv) +void RAS_TexVert::SetXYZ(const float *xyz) { - uv.getValue(m_uv1); + m_localxyz[0]= xyz[0]; m_localxyz[1]= xyz[1]; m_localxyz[2]= xyz[2]; } -void RAS_TexVert::SetUV1(const float uv[3]) +void RAS_TexVert::SetUV(int index, const MT_Point2& uv) { - m_uv1[0] = uv[0]; - m_uv1[1] = uv[1]; + uv.getValue(m_uvs[index]); } -void RAS_TexVert::SetUV2(const MT_Point2& uv) -{ - uv.getValue(m_uv2); -} - -void RAS_TexVert::SetUV2(const float uv[3]) -{ - m_uv2[0] = uv[0]; - m_uv2[1] = uv[1]; -} void RAS_TexVert::SetRGBA(const unsigned int rgba) { @@ -132,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 */ } @@ -162,12 +151,3 @@ void RAS_TexVert::Transform(const MT_Matrix4x4& mat, const MT_Matrix4x4& nmat) SetTangent((nmat*MT_Vector4(m_tangent[0], m_tangent[1], m_tangent[2], 1.0)).getValue()); } -void RAS_TexVert::TransformUV1(const MT_Matrix4x4& mat) -{ - SetUV1((mat * MT_Vector4(m_uv1[0], m_uv1[1], 0.0, 1.0)).getValue()); -} - -void RAS_TexVert::TransformUV2(const MT_Matrix4x4& mat) -{ - SetUV2((mat * MT_Vector4(m_uv2[0], m_uv2[1], 0.0, 1.0)).getValue()); -} diff --git a/source/gameengine/Rasterizer/RAS_TexVert.h b/source/gameengine/Rasterizer/RAS_TexVert.h index 98ea4dd60aa..fac41339986 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 { @@ -122,11 +115,8 @@ public: } void SetXYZ(const MT_Point3& xyz); - void SetXYZ(const float xyz[3]); - void SetUV1(const MT_Point2& uv); - void SetUV2(const MT_Point2& uv); - void SetUV1(const float uv[2]); - void SetUV2(const float uv[2]); + void SetXYZ(const float *xyz); + void SetUV(int index, const MT_Point2& uv); void SetRGBA(const unsigned int rgba); void SetNormal(const MT_Vector3& normal); @@ -139,8 +129,6 @@ public: void Transform(const class MT_Matrix4x4& mat, const class MT_Matrix4x4& nmat); - void TransformUV1(const MT_Matrix4x4& mat); - void TransformUV2(const MT_Matrix4x4& mat); // compare two vertices, to test if they can be shared, used for // splitting up based on uv's, colors, etc @@ -152,4 +140,5 @@ public: #endif }; -#endif /* __RAS_TEXVERT_H__ */ +#endif //__RAS_TEXVERT_H__ + diff --git a/source/gameengine/Rasterizer/RAS_texmatrix.cpp b/source/gameengine/Rasterizer/RAS_texmatrix.cpp index d335a38171f..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(); @@ -93,10 +93,10 @@ int main() MT_Point2 puv0={0,0}; MT_Point3 pxyz0 (0,0,128); - MT_Scalar puv1[2] = {1,0}; + MT_Scalar puv1[2]={1,0}; MT_Point3 pxyz1(128,0,128); - MT_Scalar puv2[2] = {1,1}; + MT_Scalar puv2[2]={1,1}; MT_Point3 pxyz2(128,0,0); RAS_TexVert p0(pxyz0,puv0); diff --git a/source/gameengine/Rasterizer/SConscript b/source/gameengine/Rasterizer/SConscript index 4164271ba9b..9aa7a762e9b 100644 --- a/source/gameengine/Rasterizer/SConscript +++ b/source/gameengine/Rasterizer/SConscript @@ -4,7 +4,7 @@ Import ('env') sources = env.Glob('*.cpp') -incs = '. #intern/guardedalloc #intern/string #intern/moto/include #intern/container #source/gameengine/BlenderRoutines #extern/glew/include #source/gameengine/Expressions #source/gameengine/SceneGraph #source/blender/blenkernel #source/blender/makesdna' +incs = '. #intern/guardedalloc #intern/string #intern/moto/include #intern/container #source/gameengine/BlenderRoutines #extern/glew/include #source/gameengine/Expressions #source/gameengine/SceneGraph #source/blender/blenkernel #source/blender/makesdna #source/blender/gpu' defs = [ 'GLEW_STATIC' ] |