forked from bartvdbraak/blender
2822a14e5d
to support more than 2 UV maps. This code indirectly depended on the order of OpenGL attribute ID's assigned by the OpenGL driver being the same as the attributes being declared in the GLSL shader code, which is not always the case.
164 lines
4.0 KiB
C++
164 lines
4.0 KiB
C++
/** \file gameengine/Ketsji/BL_BlenderShader.cpp
|
|
* \ingroup ketsji
|
|
*/
|
|
|
|
#include "DNA_customdata_types.h"
|
|
#include "DNA_material_types.h"
|
|
#include "DNA_scene_types.h"
|
|
|
|
#include "BLI_utildefines.h"
|
|
|
|
#include "BKE_global.h"
|
|
#include "BKE_main.h"
|
|
#include "BKE_DerivedMesh.h"
|
|
|
|
#include "BL_BlenderShader.h"
|
|
#include "BL_Material.h"
|
|
|
|
#include "GPU_extensions.h"
|
|
#include "GPU_material.h"
|
|
|
|
#include "RAS_BucketManager.h"
|
|
#include "RAS_MeshObject.h"
|
|
#include "RAS_IRasterizer.h"
|
|
|
|
BL_BlenderShader::BL_BlenderShader(KX_Scene *scene, struct Material *ma, int lightlayer)
|
|
:
|
|
mScene(scene),
|
|
mMat(ma),
|
|
mLightLayer(lightlayer),
|
|
mGPUMat(NULL)
|
|
{
|
|
mBlenderScene = scene->GetBlenderScene();
|
|
mAlphaBlend = GPU_BLEND_SOLID;
|
|
|
|
ReloadMaterial();
|
|
}
|
|
|
|
BL_BlenderShader::~BL_BlenderShader()
|
|
{
|
|
if (mGPUMat)
|
|
GPU_material_unbind(mGPUMat);
|
|
}
|
|
|
|
void BL_BlenderShader::ReloadMaterial()
|
|
{
|
|
mGPUMat = (mMat) ? GPU_material_from_blender(mBlenderScene, mMat) : NULL;
|
|
}
|
|
|
|
void BL_BlenderShader::SetProg(bool enable, double time)
|
|
{
|
|
if (VerifyShader()) {
|
|
if (enable)
|
|
GPU_material_bind(mGPUMat, mLightLayer, mBlenderScene->lay, time, 1);
|
|
else
|
|
GPU_material_unbind(mGPUMat);
|
|
}
|
|
}
|
|
|
|
int BL_BlenderShader::GetAttribNum()
|
|
{
|
|
GPUVertexAttribs attribs;
|
|
int i, enabled = 0;
|
|
|
|
if (!VerifyShader())
|
|
return enabled;
|
|
|
|
GPU_material_vertex_attributes(mGPUMat, &attribs);
|
|
|
|
for (i = 0; i < attribs.totlayer; i++)
|
|
if (attribs.layer[i].glindex+1 > enabled)
|
|
enabled= attribs.layer[i].glindex+1;
|
|
|
|
if (enabled > BL_MAX_ATTRIB)
|
|
enabled = BL_MAX_ATTRIB;
|
|
|
|
return enabled;
|
|
}
|
|
|
|
void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat)
|
|
{
|
|
GPUVertexAttribs attribs;
|
|
GPUMaterial *gpumat;
|
|
int i, attrib_num, uv = 0;
|
|
|
|
ras->SetAttribNum(0);
|
|
|
|
if (!VerifyShader())
|
|
return;
|
|
|
|
gpumat = mGPUMat;
|
|
|
|
if (ras->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) {
|
|
GPU_material_vertex_attributes(gpumat, &attribs);
|
|
attrib_num = GetAttribNum();
|
|
|
|
ras->SetTexCoordNum(0);
|
|
ras->SetAttribNum(attrib_num);
|
|
for (i = 0; i < attrib_num; i++)
|
|
ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_DISABLE, i);
|
|
|
|
for (i = 0; i < attribs.totlayer; i++) {
|
|
if (attribs.layer[i].glindex > attrib_num)
|
|
continue;
|
|
|
|
if (attribs.layer[i].type == CD_MTFACE)
|
|
ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV, attribs.layer[i].glindex, uv++);
|
|
else if (attribs.layer[i].type == CD_TANGENT)
|
|
ras->SetAttrib(RAS_IRasterizer::RAS_TEXTANGENT, attribs.layer[i].glindex);
|
|
else if (attribs.layer[i].type == CD_ORCO)
|
|
ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_ORCO, attribs.layer[i].glindex);
|
|
else if (attribs.layer[i].type == CD_NORMAL)
|
|
ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_NORM, attribs.layer[i].glindex);
|
|
else if (attribs.layer[i].type == CD_MCOL)
|
|
ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_VCOL, attribs.layer[i].glindex);
|
|
else
|
|
ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_DISABLE, attribs.layer[i].glindex);
|
|
}
|
|
}
|
|
}
|
|
|
|
void BL_BlenderShader::Update(const RAS_MeshSlot & ms, RAS_IRasterizer* rasty )
|
|
{
|
|
float obmat[4][4], viewmat[4][4], viewinvmat[4][4], obcol[4];
|
|
GPUMaterial *gpumat;
|
|
|
|
gpumat = mGPUMat;
|
|
|
|
if (!gpumat || !GPU_material_bound(gpumat))
|
|
return;
|
|
|
|
MT_Matrix4x4 model;
|
|
model.setValue(ms.m_OpenGLMatrix);
|
|
const MT_Matrix4x4& view = rasty->GetViewMatrix();
|
|
const MT_Matrix4x4& viewinv = rasty->GetViewInvMatrix();
|
|
|
|
// note: getValue gives back column major as needed by OpenGL
|
|
model.getValue((float*)obmat);
|
|
view.getValue((float*)viewmat);
|
|
viewinv.getValue((float*)viewinvmat);
|
|
|
|
if (ms.m_bObjectColor)
|
|
ms.m_RGBAcolor.getValue((float *)obcol);
|
|
else
|
|
obcol[0] = obcol[1] = obcol[2] = obcol[3] = 1.0f;
|
|
|
|
float auto_bump_scale = ms.m_pDerivedMesh!=0 ? ms.m_pDerivedMesh->auto_bump_scale : 1.0f;
|
|
GPU_material_bind_uniforms(gpumat, obmat, viewmat, viewinvmat, obcol, auto_bump_scale);
|
|
|
|
mAlphaBlend = GPU_material_alpha_blend(gpumat, obcol);
|
|
}
|
|
|
|
int BL_BlenderShader::GetAlphaBlend()
|
|
{
|
|
return mAlphaBlend;
|
|
}
|
|
|
|
bool BL_BlenderShader::Equals(BL_BlenderShader *blshader)
|
|
{
|
|
/* to avoid unneeded state switches */
|
|
return (blshader && mMat == blshader->mMat && mLightLayer == blshader->mLightLayer);
|
|
}
|
|
|
|
// eof
|