Blender V2.61 - r43446

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