1 /** \file gameengine/Ketsji/BL_BlenderShader.cpp
5 #include "DNA_customdata_types.h"
6 #include "DNA_material_types.h"
7 #include "DNA_scene_types.h"
9 #include "BKE_global.h"
11 #include "BKE_DerivedMesh.h"
13 #include "BL_BlenderShader.h"
14 #include "BL_Material.h"
16 #include "GPU_extensions.h"
17 #include "GPU_material.h"
19 #include "RAS_BucketManager.h"
20 #include "RAS_MeshObject.h"
21 #include "RAS_IRasterizer.h"
23 BL_BlenderShader::BL_BlenderShader(KX_Scene *scene, struct Material *ma, int lightlayer)
27 mLightLayer(lightlayer),
30 mBlenderScene = scene->GetBlenderScene();
31 mAlphaBlend = GPU_BLEND_SOLID;
36 BL_BlenderShader::~BL_BlenderShader()
39 GPU_material_unbind(mGPUMat);
42 void BL_BlenderShader::ReloadMaterial()
44 mGPUMat = (mMat) ? GPU_material_from_blender(mBlenderScene, mMat) : NULL;
47 void BL_BlenderShader::SetProg(bool enable, double time)
51 GPU_material_bind(mGPUMat, mLightLayer, mBlenderScene->lay, time, 1);
53 GPU_material_unbind(mGPUMat);
57 int BL_BlenderShader::GetAttribNum()
59 GPUVertexAttribs attribs;
65 GPU_material_vertex_attributes(mGPUMat, &attribs);
67 for(i = 0; i < attribs.totlayer; i++)
68 if(attribs.layer[i].glindex+1 > enabled)
69 enabled= attribs.layer[i].glindex+1;
71 if(enabled > BL_MAX_ATTRIB)
72 enabled = BL_MAX_ATTRIB;
77 void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat)
79 GPUVertexAttribs attribs;
90 if(ras->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) {
91 GPU_material_vertex_attributes(gpumat, &attribs);
92 attrib_num = GetAttribNum();
94 ras->SetTexCoordNum(0);
95 ras->SetAttribNum(attrib_num);
96 for(i=0; i<attrib_num; i++)
97 ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_DISABLE, i);
99 for(i = 0; i < attribs.totlayer; i++) {
100 if(attribs.layer[i].glindex > attrib_num)
103 if(attribs.layer[i].type == CD_MTFACE) {
104 if(!mat->uvName.IsEmpty() && strcmp(mat->uvName.ReadPtr(), attribs.layer[i].name) == 0)
105 ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex);
106 else if(!mat->uv2Name.IsEmpty() && strcmp(mat->uv2Name.ReadPtr(), attribs.layer[i].name) == 0)
107 ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV2, attribs.layer[i].glindex);
109 ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex);
111 else if(attribs.layer[i].type == CD_TANGENT)
112 ras->SetAttrib(RAS_IRasterizer::RAS_TEXTANGENT, attribs.layer[i].glindex);
113 else if(attribs.layer[i].type == CD_ORCO)
114 ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_ORCO, attribs.layer[i].glindex);
115 else if(attribs.layer[i].type == CD_NORMAL)
116 ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_NORM, attribs.layer[i].glindex);
117 else if(attribs.layer[i].type == CD_MCOL)
118 ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_VCOL, attribs.layer[i].glindex);
120 ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_DISABLE, attribs.layer[i].glindex);
125 void BL_BlenderShader::Update(const RAS_MeshSlot & ms, RAS_IRasterizer* rasty )
127 float obmat[4][4], viewmat[4][4], viewinvmat[4][4], obcol[4];
132 if(!gpumat || !GPU_material_bound(gpumat))
136 model.setValue(ms.m_OpenGLMatrix);
137 const MT_Matrix4x4& view = rasty->GetViewMatrix();
138 const MT_Matrix4x4& viewinv = rasty->GetViewInvMatrix();
140 // note: getValue gives back column major as needed by OpenGL
141 model.getValue((float*)obmat);
142 view.getValue((float*)viewmat);
143 viewinv.getValue((float*)viewinvmat);
145 if(ms.m_bObjectColor)
146 ms.m_RGBAcolor.getValue((float*)obcol);
148 obcol[0]= obcol[1]= obcol[2]= obcol[3]= 1.0f;
150 GPU_material_bind_uniforms(gpumat, obmat, viewmat, viewinvmat, obcol, ms.m_pDerivedMesh->auto_bump_scale);
152 mAlphaBlend = GPU_material_alpha_blend(gpumat, obcol);
155 int BL_BlenderShader::GetAlphaBlend()
160 bool BL_BlenderShader::Equals(BL_BlenderShader *blshader)
162 /* to avoid unneeded state switches */
163 return (blshader && mMat == blshader->mMat && mLightLayer == blshader->mLightLayer);