BGE: Adding material IPO support to GLSL materials
authorMitchell Stokes <mogurijin@gmail.com>
Tue, 12 May 2015 06:05:04 +0000 (23:05 -0700)
committerMitchell Stokes <mogurijin@gmail.com>
Tue, 12 May 2015 06:05:04 +0000 (23:05 -0700)
Most of this patch was created by Daniel Stokes, I'm mostly just cleaning
it up and testing it. Still todo: hardness. I need to figure out how to
handle the integer -> float conversion on a dynamic uniform.

Reviewers: psy-fi, brecht

Reviewed By: psy-fi

Subscribers: psy-fi

Differential Revision: https://developer.blender.org/D511

source/blender/gpu/GPU_material.h
source/blender/gpu/intern/gpu_codegen.c
source/blender/gpu/intern/gpu_material.c
source/gameengine/Ketsji/KX_BlenderMaterial.cpp
source/gameengine/Ketsji/KX_BlenderMaterial.h
source/gameengine/Ketsji/KX_IpoConvert.cpp
source/gameengine/Ketsji/KX_MaterialIpoController.cpp

index 7bb044a1ae3840059f689b0283e14fe9eb235cce..1fb2518c07cad70317d0f3ce55efe2ff804cdc41 100644 (file)
@@ -154,6 +154,14 @@ typedef enum GPUDynamicType {
        GPU_DYNAMIC_MIST_COLOR = 26,
        GPU_DYNAMIC_HORIZON_COLOR = 27,
        GPU_DYNAMIC_AMBIENT_COLOR = 28,
+       GPU_DYNAMIC_MAT_DIFFRGB = 29,
+       GPU_DYNAMIC_MAT_REF = 30,
+       GPU_DYNAMIC_MAT_SPECRGB = 31,
+       GPU_DYNAMIC_MAT_SPEC = 32,
+       GPU_DYNAMIC_MAT_HARD = 33,
+       GPU_DYNAMIC_MAT_EMIT = 34,
+       GPU_DYNAMIC_MAT_AMB = 35,
+       GPU_DYNAMIC_MAT_ALPHA = 36,
 } GPUDynamicType;
 
 GPUNodeLink *GPU_attribute(CustomDataType type, const char *name);
index e9bc4002032d1091a30286e8150c1b5c2f925f92..e92b58932a3d1e58b5bd71b817d6b6fd3b15afbd 100644 (file)
@@ -852,10 +852,19 @@ void GPU_pass_update_uniforms(GPUPass *pass)
                return;
 
        /* pass dynamic inputs to opengl, others were removed */
-       for (input = inputs->first; input; input = input->next)
-               if (!(input->ima || input->tex || input->prv))
-                       GPU_shader_uniform_vector(shader, input->shaderloc, input->type, 1,
-                               input->dynamicvec);
+       for (input = inputs->first; input; input = input->next) {
+               if (!(input->ima || input->tex || input->prv)) {
+                       if (input->dynamictype == GPU_DYNAMIC_MAT_HARD) {
+                               // The hardness is actually a short pointer, so we convert it here
+                               float val = (float)(*(short*)input->dynamicvec);
+                               GPU_shader_uniform_vector(shader, input->shaderloc, 1, 1, &val);
+                       }
+                       else {
+                               GPU_shader_uniform_vector(shader, input->shaderloc, input->type, 1,
+                                       input->dynamicvec);
+                       }
+               }
+       }
 }
 
 void GPU_pass_unbind(GPUPass *pass)
index 12672b5f5af7f5421a3ae9a6675361eabffcc6f8..774dee9ebc21ae2ab12f86666ee5c4e2906617c4 100644 (file)
@@ -1449,7 +1449,6 @@ static void do_material_tex(GPUShadeInput *shi)
 
 void GPU_shadeinput_set(GPUMaterial *mat, Material *ma, GPUShadeInput *shi)
 {
-       float hard = ma->har;
        float one = 1.0f;
 
        memset(shi, 0, sizeof(*shi));
@@ -1457,20 +1456,20 @@ void GPU_shadeinput_set(GPUMaterial *mat, Material *ma, GPUShadeInput *shi)
        shi->gpumat = mat;
        shi->mat = ma;
 
-       GPU_link(mat, "set_rgb", GPU_uniform(&ma->r), &shi->rgb);
-       GPU_link(mat, "set_rgb", GPU_uniform(&ma->specr), &shi->specrgb);
+       GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&ma->r, GPU_DYNAMIC_MAT_DIFFRGB, NULL), &shi->rgb);
+       GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&ma->specr, GPU_DYNAMIC_MAT_SPECRGB, NULL), &shi->specrgb);
        GPU_link(mat, "shade_norm", GPU_builtin(GPU_VIEW_NORMAL), &shi->vn);
 
        if (mat->alpha)
-               GPU_link(mat, "set_value", GPU_uniform(&ma->alpha), &shi->alpha);
+               GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->alpha, GPU_DYNAMIC_MAT_ALPHA, NULL), &shi->alpha);
        else
                GPU_link(mat, "set_value", GPU_uniform(&one), &shi->alpha);
 
-       GPU_link(mat, "set_value", GPU_uniform(&ma->ref), &shi->refl);
-       GPU_link(mat, "set_value", GPU_uniform(&ma->spec), &shi->spec);
-       GPU_link(mat, "set_value", GPU_uniform(&ma->emit), &shi->emit);
-       GPU_link(mat, "set_value", GPU_uniform(&hard), &shi->har);
-       GPU_link(mat, "set_value", GPU_uniform(&ma->amb), &shi->amb);
+       GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->ref, GPU_DYNAMIC_MAT_REF, NULL), &shi->refl);
+       GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->spec, GPU_DYNAMIC_MAT_SPEC, NULL), &shi->spec);
+       GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->emit, GPU_DYNAMIC_MAT_EMIT, NULL), &shi->emit);
+       GPU_link(mat, "set_value", GPU_dynamic_uniform((float*)&ma->har, GPU_DYNAMIC_MAT_HARD, NULL), &shi->har);
+       GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->amb, GPU_DYNAMIC_MAT_AMB, NULL), &shi->amb);
        GPU_link(mat, "set_value", GPU_uniform(&ma->spectra), &shi->spectra);
        GPU_link(mat, "shade_view", GPU_builtin(GPU_VIEW_POSITION), &shi->view);
        GPU_link(mat, "vcol_attribute", GPU_attribute(CD_MCOL, ""), &shi->vcol);
index 9f0b582045f9095269ccf969d827d8e467363138..7ec2673bf1f5d082d126ff7f0e8d9bd37efbc82b 100644 (file)
@@ -94,6 +94,21 @@ void KX_BlenderMaterial::Initialize(
                ((data->ras_mode &TEX)),
                game
        );
+       Material *ma = data->material;
+
+       // Save material data to restore on exit
+       mSavedData.r = ma->r;
+       mSavedData.g = ma->g;
+       mSavedData.b = ma->b;
+       mSavedData.a = ma->alpha;
+       mSavedData.specr = ma->specr;
+       mSavedData.specg = ma->specg;
+       mSavedData.specb = ma->specb;
+       mSavedData.spec = ma->spec;
+       mSavedData.ref = ma->ref;
+       mSavedData.hardness = ma->har;
+       mSavedData.emit = ma->emit;
+
        mMaterial = data;
        mShader = 0;
        mBlenderShader = 0;
@@ -124,6 +139,20 @@ void KX_BlenderMaterial::Initialize(
 
 KX_BlenderMaterial::~KX_BlenderMaterial()
 {
+       Material *ma = mMaterial->material;
+       // Restore Blender material data
+       ma->r = mSavedData.r;
+       ma->g = mSavedData.g;
+       ma->b = mSavedData.b;
+       ma->alpha = mSavedData.a;
+       ma->specr = mSavedData.specr;
+       ma->specg = mSavedData.specg;
+       ma->specb = mSavedData.specb;
+       ma->spec = mSavedData.spec;
+       ma->ref = mSavedData.ref;
+       ma->har = mSavedData.hardness;
+       ma->emit = mSavedData.emit;
+
        // cleanup work
        if (mConstructed)
                // clean only if material was actually used
@@ -793,17 +822,19 @@ void KX_BlenderMaterial::UpdateIPO(
        )
 {
        // only works one deep now
-       mMaterial->speccolor[0] = (float)(specrgb)[0];
-       mMaterial->speccolor[1] = (float)(specrgb)[1];
-       mMaterial->speccolor[2] = (float)(specrgb)[2];
-       mMaterial->matcolor[0]  = (float)(rgba[0]);
-       mMaterial->matcolor[1]  = (float)(rgba[1]);
-       mMaterial->matcolor[2]  = (float)(rgba[2]);
-       mMaterial->alpha                = (float)(alpha);
-       mMaterial->hard                 = (float)(hard);
-       mMaterial->emit                 = (float)(emit);
-       mMaterial->spec_f               = (float)(spec);
-       mMaterial->ref                  = (float)(ref);
+
+       // GLSL                                                 Multitexture                            Input
+       mMaterial->material->specr      = mMaterial->speccolor[0]       = (float)(specrgb)[0];
+       mMaterial->material->specg      = mMaterial->speccolor[1]       = (float)(specrgb)[1];
+       mMaterial->material->specb      = mMaterial->speccolor[2]       = (float)(specrgb)[2];
+       mMaterial->material->r          = mMaterial->matcolor[0]        = (float)(rgba[0]);
+       mMaterial->material->g          = mMaterial->matcolor[1]        = (float)(rgba[1]);
+       mMaterial->material->b          = mMaterial->matcolor[2]        = (float)(rgba[2]);
+       mMaterial->material->alpha      = mMaterial->alpha                      = (float)(rgba[3]);
+       mMaterial->material->har        = mMaterial->hard                       = (float)(hard);
+       mMaterial->material->emit       = mMaterial->emit                       = (float)(emit);
+       mMaterial->material->spec       = mMaterial->spec_f                     = (float)(spec);
+       mMaterial->material->ref        = mMaterial->ref                        = (float)(ref);
 }
 
 void KX_BlenderMaterial::Replace_IScene(SCA_IScene *val)
index b7c64215eaf34d7a68fe21fbe86f80bd046010ef..23921588d6a9323d290b184418fb03e5ff6045c6 100644 (file)
@@ -134,6 +134,15 @@ private:
        bool                    mConstructed;                   // if false, don't clean on exit
        int                             mLightLayer;
 
+       struct {
+               float r, g, b, a;
+               float specr, specg, specb;
+               float spec;
+               float ref;
+               float hardness;
+               float emit;
+       } mSavedData;
+
        void InitTextures();
 
        void SetBlenderGLSLShader();
index 441c16176aa376538ea3a2c52a09c915f4562abf..7b00760ee7b7bdc8090bd834832bc0aed75b2dd6 100644 (file)
@@ -396,7 +396,7 @@ SG_Controller *BL_CreateMaterialIpo(
                ipocontr->AddInterpolator(interpolator);
        }
 
-       if ((sinterp = adtList->GetScalarInterpolator("specularity", 0))) {
+       if ((sinterp = adtList->GetScalarInterpolator("specular_intensity", 0))) {
                if (!ipocontr) {
                        ipocontr = new KX_MaterialIpoController(matname_hash);
                }
@@ -404,7 +404,7 @@ SG_Controller *BL_CreateMaterialIpo(
                ipocontr->AddInterpolator(interpolator);
        }
 
-       if ((sinterp = adtList->GetScalarInterpolator("diffuse_reflection", 0))) {
+       if ((sinterp = adtList->GetScalarInterpolator("diffuse_intensity", 0))) {
                if (!ipocontr) {
                        ipocontr = new KX_MaterialIpoController(matname_hash);
                }
index a9617aa47b8c6936d4dc2ce87c14b2b6ce3c7f73..1faf8f17d54e2043b04abe8002bbc46d7a944d99 100644 (file)
@@ -32,21 +32,6 @@ bool KX_MaterialIpoController::Update(double currentTime)
 {
        if (m_modified)
        {
-               m_rgba[0]=0;
-               m_rgba[1]=0;
-               m_rgba[2]=0;
-               m_rgba[3]=0;
-       
-               m_specrgb[0] =0;
-               m_specrgb[1] =0;
-               m_specrgb[2] =0;
-               m_hard =0;
-               m_spec=0;
-               m_ref=0;
-               m_emit=0;
-               m_alpha = 0;
-
-
                T_InterpolatorList::iterator i;
                for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
                        (*i)->Execute(m_ipotime);