diff options
author | Mitchell Stokes <mogurijin@gmail.com> | 2015-12-07 02:24:55 +0300 |
---|---|---|
committer | Mitchell Stokes <mogurijin@gmail.com> | 2015-12-08 06:05:09 +0300 |
commit | fe2f3a131d96e4b0d1c85e1379b30c73f6378ffd (patch) | |
tree | 90b2b683fe86eb62c880995986573993807aa0cb /source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp | |
parent | 9d03307033338dc6ce57a2258e4dd01d09f1dcb3 (diff) |
OpenGL/BGE: Remove RAS_StorageIM (glBegin/glEnd rendering of mesh data)
The only use we had for RAS_StorageIM was to render derived meshes using
Blender's mesh drawing. This is now handled as a special case in
RAS_OpenGLRasterizer instead of in RAS_StorageIM.
We are now left with RAS_StorageVA and RAS_StorageVBO. At the moment
vertex arrays are still the default since our vertex array with display
lists implementation is still much faster than our VBO code in a lot of
cases. As we improve our VBO code, we can drop vertex arrays since
Blender's minimum OpenGL version is being bumped up to 2.1, which
supports VBOs.
Diffstat (limited to 'source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp')
-rw-r--r-- | source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp | 117 |
1 files changed, 97 insertions, 20 deletions
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index 4629b91b3e4..8ba4ab715e2 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -47,15 +47,16 @@ #include "RAS_OpenGLLight.h" -#include "RAS_StorageIM.h" #include "RAS_StorageVA.h" #include "RAS_StorageVBO.h" #include "GPU_draw.h" #include "GPU_material.h" +#include "GPU_extensions.h" extern "C"{ #include "BLF_api.h" + #include "BKE_DerivedMesh.h" } @@ -83,7 +84,7 @@ static GLuint right_eye_vinterlace_mask[32]; */ static GLuint hinterlace_mask[33]; -RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas, int storage) +RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas, RAS_STORAGE_TYPE storage) :RAS_IRasterizer(canvas), m_2DCanvas(canvas), m_fogenabled(false), @@ -122,22 +123,15 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas, int storage) m_prevafvalue = GPU_get_anisotropic(); - if (m_storage_type == RAS_VBO /*|| m_storage_type == RAS_AUTO_STORAGE && GLEW_ARB_vertex_buffer_object*/) - { + 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_attrib_layer); - m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib, m_attrib_layer); - m_storage_type = RAS_VBO; } - else if ((m_storage_type == RAS_VA) || (m_storage_type == RAS_AUTO_STORAGE && GLEW_VERSION_1_1)) - { + else if ((m_storage_type == RAS_VA) || (m_storage_type == RAS_AUTO_STORAGE)) { m_storage = new RAS_StorageVA(&m_texco_num, m_texco, &m_attrib_num, m_attrib, m_attrib_layer); - m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib, m_attrib_layer); - 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_attrib_layer); - m_storage_type = RAS_IMMEDIATE; + else { + printf("Unknown rasterizer storage type, falling back to vertex arrays\n"); + m_storage = new RAS_StorageVA(&m_texco_num, m_texco, &m_attrib_num, m_attrib, m_attrib_layer); } glGetIntegerv(GL_MAX_LIGHTS, (GLint *) &m_numgllights); @@ -151,8 +145,6 @@ 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; @@ -321,9 +313,6 @@ void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode) glDisable(GL_CULL_FACE); m_storage->SetDrawingMode(drawingmode); - if (m_failsafe_storage && m_failsafe_storage != m_storage) { - m_failsafe_storage->SetDrawingMode(drawingmode); - } } int RAS_OpenGLRasterizer::GetDrawingMode() @@ -735,11 +724,99 @@ void RAS_OpenGLRasterizer::SetAttrib(TexCoGen coords, int unit, int layer) void RAS_OpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms) { if (ms.m_pDerivedMesh) - m_failsafe_storage->IndexPrimitives(ms); + DrawDerivedMesh(ms); else m_storage->IndexPrimitives(ms); } +// Code for hooking into Blender's mesh drawing for derived meshes. +// If/when we use more of Blender's drawing code, we may be able to +// clean this up +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 DMDrawOption CheckTexDM(MTexPoly *mtexpoly, const bool has_mcol, int matnr) +{ + + // index is the original face index, retrieve the polygon + if (matnr == current_blmat_nr && + (mtexpoly == NULL || mtexpoly->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::DrawDerivedMesh(class RAS_MeshSlot &ms) +{ + // 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 = m_drawingmode <= RAS_IRasterizer::KX_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 (!current_wireframe && blscene && blmat) + GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat, false), ¤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, DM_DRAW_USE_ACTIVE_UV); + } +} + void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat) { glMatrixMode(GL_PROJECTION); |