Blender  V2.59
BL_BlenderShader.cpp
Go to the documentation of this file.
00001 
00005 #include "DNA_customdata_types.h"
00006 #include "DNA_material_types.h"
00007 #include "DNA_scene_types.h"
00008 
00009 #include "BKE_global.h"
00010 #include "BKE_main.h"
00011 
00012 #include "BL_BlenderShader.h"
00013 #include "BL_Material.h"
00014 
00015 #include "GPU_extensions.h"
00016 #include "GPU_material.h"
00017 
00018 #include "RAS_BucketManager.h"
00019 #include "RAS_MeshObject.h"
00020 #include "RAS_IRasterizer.h"
00021  
00022 BL_BlenderShader::BL_BlenderShader(KX_Scene *scene, struct Material *ma, int lightlayer)
00023 :
00024         mScene(scene),
00025         mMat(ma),
00026         mLightLayer(lightlayer),
00027         mGPUMat(NULL)
00028 {
00029         mBlenderScene = scene->GetBlenderScene();
00030         mBlendMode = GPU_BLEND_SOLID;
00031 
00032         ReloadMaterial();
00033 }
00034 
00035 BL_BlenderShader::~BL_BlenderShader()
00036 {
00037         if(mGPUMat)
00038                 GPU_material_unbind(mGPUMat);
00039 }
00040 
00041 void BL_BlenderShader::ReloadMaterial()
00042 {
00043         mGPUMat = (mMat) ? GPU_material_from_blender(mBlenderScene, mMat) : NULL;
00044 }
00045 
00046 void BL_BlenderShader::SetProg(bool enable, double time)
00047 {
00048         if(VerifyShader()) {
00049                 if(enable)
00050                         GPU_material_bind(mGPUMat, mLightLayer, mBlenderScene->lay, time, 1);
00051                 else
00052                         GPU_material_unbind(mGPUMat);
00053         }
00054 }
00055 
00056 int BL_BlenderShader::GetAttribNum()
00057 {
00058         GPUVertexAttribs attribs;
00059         int i, enabled = 0;
00060 
00061         if(!VerifyShader())
00062                 return enabled;
00063 
00064         GPU_material_vertex_attributes(mGPUMat, &attribs);
00065 
00066     for(i = 0; i < attribs.totlayer; i++)
00067                 if(attribs.layer[i].glindex+1 > enabled)
00068                         enabled= attribs.layer[i].glindex+1;
00069         
00070         if(enabled > BL_MAX_ATTRIB)
00071                 enabled = BL_MAX_ATTRIB;
00072 
00073         return enabled;
00074 }
00075 
00076 void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat)
00077 {
00078         GPUVertexAttribs attribs;
00079         GPUMaterial *gpumat;
00080         int i, attrib_num;
00081 
00082         ras->SetAttribNum(0);
00083 
00084         if(!VerifyShader())
00085                 return;
00086         
00087         gpumat = mGPUMat;
00088 
00089         if(ras->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) {
00090                 GPU_material_vertex_attributes(gpumat, &attribs);
00091                 attrib_num = GetAttribNum();
00092 
00093                 ras->SetTexCoordNum(0);
00094                 ras->SetAttribNum(attrib_num);
00095                 for(i=0; i<attrib_num; i++)
00096                         ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_DISABLE, i);
00097 
00098                 for(i = 0; i < attribs.totlayer; i++) {
00099                         if(attribs.layer[i].glindex > attrib_num)
00100                                 continue;
00101 
00102                         if(attribs.layer[i].type == CD_MTFACE) {
00103                                 if(!mat->uvName.IsEmpty() && strcmp(mat->uvName.ReadPtr(), attribs.layer[i].name) == 0)
00104                                         ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex);
00105                                 else if(!mat->uv2Name.IsEmpty() && strcmp(mat->uv2Name.ReadPtr(), attribs.layer[i].name) == 0)
00106                                         ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV2, attribs.layer[i].glindex);
00107                                 else
00108                                         ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex);
00109                         }
00110                         else if(attribs.layer[i].type == CD_TANGENT)
00111                                 ras->SetAttrib(RAS_IRasterizer::RAS_TEXTANGENT, attribs.layer[i].glindex);
00112                         else if(attribs.layer[i].type == CD_ORCO)
00113                                 ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_ORCO, attribs.layer[i].glindex);
00114                         else if(attribs.layer[i].type == CD_NORMAL)
00115                                 ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_NORM, attribs.layer[i].glindex);
00116                         else if(attribs.layer[i].type == CD_MCOL)
00117                                 ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_VCOL, attribs.layer[i].glindex);
00118                         else
00119                                 ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_DISABLE, attribs.layer[i].glindex);
00120                 }
00121         }
00122 }
00123 
00124 void BL_BlenderShader::Update(const RAS_MeshSlot & ms, RAS_IRasterizer* rasty )
00125 {
00126         float obmat[4][4], viewmat[4][4], viewinvmat[4][4], obcol[4];
00127         GPUMaterial *gpumat;
00128 
00129         gpumat = mGPUMat;
00130 
00131         if(!gpumat || !GPU_material_bound(gpumat))
00132                 return;
00133 
00134         MT_Matrix4x4 model;
00135         model.setValue(ms.m_OpenGLMatrix);
00136         const MT_Matrix4x4& view = rasty->GetViewMatrix();
00137         const MT_Matrix4x4& viewinv = rasty->GetViewInvMatrix();
00138 
00139         // note: getValue gives back column major as needed by OpenGL
00140         model.getValue((float*)obmat);
00141         view.getValue((float*)viewmat);
00142         viewinv.getValue((float*)viewinvmat);
00143 
00144         if(ms.m_bObjectColor)
00145                 ms.m_RGBAcolor.getValue((float*)obcol);
00146         else
00147                 obcol[0]= obcol[1]= obcol[2]= obcol[3]= 1.0f;
00148 
00149         GPU_material_bind_uniforms(gpumat, obmat, viewmat, viewinvmat, obcol);
00150 
00151         mBlendMode = GPU_material_blend_mode(gpumat, obcol);
00152 }
00153 
00154 int BL_BlenderShader::GetBlendMode()
00155 {
00156         return mBlendMode;
00157 }
00158 
00159 bool BL_BlenderShader::Equals(BL_BlenderShader *blshader)
00160 {
00161         /* to avoid unneeded state switches */
00162         return (blshader && mMat == blshader->mMat && mLightLayer == blshader->mLightLayer);
00163 }
00164 
00165 // eof