diff --git a/src/gl/gl3device.cpp b/src/gl/gl3device.cpp index ecb781f4..90ac2993 100644 --- a/src/gl/gl3device.cpp +++ b/src/gl/gl3device.cpp @@ -137,6 +137,7 @@ int32 u_matColor; int32 u_surfProps; Shader *defaultShader, *defaultShader_noAT; +Shader *defaultShader_fullLight, *defaultShader_fullLight_noAT; static bool32 stateDirty = 1; static bool32 sceneDirty = 1; @@ -996,7 +997,7 @@ setLights(WorldLights *lightData) uniformObject.lightParams[n].type = 1.0f; uniformObject.lightColor[n] = l->color; memcpy(&uniformObject.lightDirection[n], &l->getFrame()->getLTM()->at, sizeof(V3d)); - bits |= VSLIGHT_POINT; + bits |= VSLIGHT_DIRECT; n++; if(n >= MAX_LIGHTS) goto out; @@ -1833,13 +1834,20 @@ initOpenGL(void) #include "shaders/default_vs_gl.inc" #include "shaders/simple_fs_gl.inc" const char *vs[] = { shaderDecl, header_vert_src, default_vert_src, nil }; + const char *vs_fullLight[] = { shaderDecl, "#define DIRECTIONALS\n#define POINTLIGHTS\n#define SPOTLIGHTS\n", header_vert_src, default_vert_src, nil }; const char *fs[] = { shaderDecl, header_frag_src, simple_frag_src, nil }; + const char *fs_noAT[] = { shaderDecl, "#define NO_ALPHATEST\n", header_frag_src, simple_frag_src, nil }; + defaultShader = Shader::create(vs, fs); assert(defaultShader); - const char *fs_noAT[] = { shaderDecl, "#define NO_ALPHATEST\n", header_frag_src, simple_frag_src, nil }; defaultShader_noAT = Shader::create(vs, fs_noAT); assert(defaultShader_noAT); + defaultShader_fullLight = Shader::create(vs_fullLight, fs); + assert(defaultShader_fullLight); + defaultShader_fullLight_noAT = Shader::create(vs_fullLight, fs_noAT); + assert(defaultShader_fullLight_noAT); + openIm2D(); openIm3D(); @@ -1856,6 +1864,10 @@ termOpenGL(void) defaultShader = nil; defaultShader_noAT->destroy(); defaultShader_noAT = nil; + defaultShader_fullLight->destroy(); + defaultShader_fullLight = nil; + defaultShader_fullLight_noAT->destroy(); + defaultShader_fullLight_noAT = nil; glDeleteTextures(1, &whitetex); whitetex = nil; diff --git a/src/gl/gl3matfx.cpp b/src/gl/gl3matfx.cpp index 6ad662e7..06b01c15 100644 --- a/src/gl/gl3matfx.cpp +++ b/src/gl/gl3matfx.cpp @@ -24,26 +24,37 @@ namespace gl3 { #ifdef RW_OPENGL -static Shader *envShader; +static Shader *envShader, *envShader_noAT; +static Shader *envShader_fullLight, *envShader_fullLight_noAT; static int32 u_texMatrix; static int32 u_fxparams; static int32 u_colorClamp; static int32 u_envColor; void -matfxDefaultRender(InstanceDataHeader *header, InstanceData *inst, uint32 flags) +matfxDefaultRender(InstanceDataHeader *header, InstanceData *inst, int32 vsBits, uint32 flags) { Material *m; m = inst->material; - defaultShader->use(); - setMaterial(flags, m->color, m->surfaceProps); setTexture(0, m->texture); rw::SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF); + if((vsBits & VSLIGHT_MASK) == 0){ + if(getAlphaTest()) + defaultShader->use(); + else + defaultShader_noAT->use(); + }else{ + if(getAlphaTest()) + defaultShader_fullLight->use(); + else + defaultShader_fullLight_noAT->use(); + } + drawInst(header, inst); } @@ -82,18 +93,16 @@ uploadEnvMatrix(Frame *frame) } void -matfxEnvRender(InstanceDataHeader *header, InstanceData *inst, uint32 flags, MatFX::Env *env) +matfxEnvRender(InstanceDataHeader *header, InstanceData *inst, int32 vsBits, uint32 flags, MatFX::Env *env) { Material *m; m = inst->material; if(env->tex == nil || env->coefficient == 0.0f){ - matfxDefaultRender(header, inst, flags); + matfxDefaultRender(header, inst, vsBits, flags); return; } - envShader->use(); - setTexture(0, m->texture); setTexture(1, env->tex); uploadEnvMatrix(env->frame); @@ -123,6 +132,18 @@ matfxEnvRender(InstanceDataHeader *header, InstanceData *inst, uint32 flags, Mat rw::SetRenderState(VERTEXALPHA, 1); rw::SetRenderState(SRCBLEND, BLENDONE); + if((vsBits & VSLIGHT_MASK) == 0){ + if(getAlphaTest()) + envShader->use(); + else + envShader_noAT->use(); + }else{ + if(getAlphaTest()) + envShader_fullLight->use(); + else + envShader_fullLight_noAT->use(); + } + drawInst(header, inst); rw::SetRenderState(SRCBLEND, BLENDSRCALPHA); @@ -133,7 +154,7 @@ matfxRenderCB(Atomic *atomic, InstanceDataHeader *header) { uint32 flags = atomic->geometry->flags; setWorldMatrix(atomic->getFrame()->getLTM()); - lightingCB(atomic); + int32 vsBits = lightingCB(atomic); setupVertexInput(header); @@ -146,13 +167,13 @@ matfxRenderCB(Atomic *atomic, InstanceDataHeader *header) MatFX *matfx = MatFX::get(inst->material); if(matfx == nil) - matfxDefaultRender(header, inst, flags); + matfxDefaultRender(header, inst, vsBits, flags); else switch(matfx->type){ case MatFX::ENVMAP: - matfxEnvRender(header, inst, flags, &matfx->fx[0].env); + matfxEnvRender(header, inst, vsBits, flags, &matfx->fx[0].env); break; default: - matfxDefaultRender(header, inst, flags); + matfxDefaultRender(header, inst, vsBits, flags); break; } inst++; @@ -179,9 +200,19 @@ matfxOpen(void *o, int32, int32) #include "shaders/matfx_gl.inc" const char *vs[] = { shaderDecl, header_vert_src, matfx_env_vert_src, nil }; + const char *vs_fullLight[] = { shaderDecl, "#define DIRECTIONALS\n#define POINTLIGHTS\n#define SPOTLIGHTS\n", header_vert_src, matfx_env_vert_src, nil }; const char *fs[] = { shaderDecl, header_frag_src, matfx_env_frag_src, nil }; + const char *fs_noAT[] = { shaderDecl, "#define NO_ALPHATEST\n", header_frag_src, matfx_env_frag_src, nil }; + envShader = Shader::create(vs, fs); assert(envShader); + envShader_noAT = Shader::create(vs, fs_noAT); + assert(envShader_noAT); + + envShader_fullLight = Shader::create(vs_fullLight, fs); + assert(envShader_fullLight); + envShader_fullLight_noAT = Shader::create(vs_fullLight, fs_noAT); + assert(envShader_fullLight_noAT); return o; } @@ -194,6 +225,12 @@ matfxClose(void *o, int32, int32) envShader->destroy(); envShader = nil; + envShader_noAT->destroy(); + envShader_noAT = nil; + envShader_fullLight->destroy(); + envShader_fullLight = nil; + envShader_fullLight_noAT->destroy(); + envShader_fullLight_noAT = nil; return o; } diff --git a/src/gl/gl3render.cpp b/src/gl/gl3render.cpp index 011475b8..4dd79ba7 100644 --- a/src/gl/gl3render.cpp +++ b/src/gl/gl3render.cpp @@ -142,7 +142,7 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header) uint32 flags = atomic->geometry->flags; setWorldMatrix(atomic->getFrame()->getLTM()); - lightingCB(atomic); + int32 vsBits = lightingCB(atomic); setupVertexInput(header); @@ -158,10 +158,17 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header) rw::SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF); - if(getAlphaTest()) - defaultShader->use(); - else - defaultShader_noAT->use(); + if((vsBits & VSLIGHT_MASK) == 0){ + if(getAlphaTest()) + defaultShader->use(); + else + defaultShader_noAT->use(); + }else{ + if(getAlphaTest()) + defaultShader_fullLight->use(); + else + defaultShader_fullLight_noAT->use(); + } drawInst(header, inst); inst++; diff --git a/src/gl/gl3skin.cpp b/src/gl/gl3skin.cpp index b2b58315..6b69bbdd 100644 --- a/src/gl/gl3skin.cpp +++ b/src/gl/gl3skin.cpp @@ -24,7 +24,8 @@ namespace gl3 { #ifdef RW_OPENGL -static Shader *skinShader; +static Shader *skinShader, *skinShader_noAT; +static Shader *skinShader_fullLight, *skinShader_fullLight_noAT; static int32 u_boneMatrices; void @@ -254,15 +255,13 @@ skinRenderCB(Atomic *atomic, InstanceDataHeader *header) uint32 flags = atomic->geometry->flags; setWorldMatrix(atomic->getFrame()->getLTM()); - lightingCB(atomic); + int32 vsBits = lightingCB(atomic); setupVertexInput(header); InstanceData *inst = header->inst; int32 n = header->numMeshes; - skinShader->use(); - uploadSkinMatrices(atomic); while(n--){ @@ -274,6 +273,18 @@ skinRenderCB(Atomic *atomic, InstanceDataHeader *header) rw::SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF); + if((vsBits & VSLIGHT_MASK) == 0){ + if(getAlphaTest()) + skinShader->use(); + else + skinShader_noAT->use(); + }else{ + if(getAlphaTest()) + skinShader_fullLight->use(); + else + skinShader_fullLight_noAT->use(); + } + drawInst(header, inst); inst++; } @@ -288,9 +299,19 @@ skinOpen(void *o, int32, int32) #include "shaders/simple_fs_gl.inc" #include "shaders/skin_gl.inc" const char *vs[] = { shaderDecl, header_vert_src, skin_vert_src, nil }; + const char *vs_fullLight[] = { shaderDecl, "#define DIRECTIONALS\n#define POINTLIGHTS\n#define SPOTLIGHTS\n", header_vert_src, skin_vert_src, nil }; const char *fs[] = { shaderDecl, header_frag_src, simple_frag_src, nil }; + const char *fs_noAT[] = { shaderDecl, "#define NO_ALPHATEST\n", header_frag_src, simple_frag_src, nil }; + skinShader = Shader::create(vs, fs); assert(skinShader); + skinShader_noAT = Shader::create(vs, fs_noAT); + assert(skinShader_noAT); + + skinShader_fullLight = Shader::create(vs_fullLight, fs); + assert(skinShader_fullLight); + skinShader_fullLight_noAT = Shader::create(vs_fullLight, fs_noAT); + assert(skinShader_fullLight_noAT); return o; } @@ -303,6 +324,12 @@ skinClose(void *o, int32, int32) skinShader->destroy(); skinShader = nil; + skinShader_noAT->destroy(); + skinShader_noAT = nil; + skinShader_fullLight->destroy(); + skinShader_fullLight = nil; + skinShader_fullLight_noAT->destroy(); + skinShader_fullLight_noAT = nil; return o; } diff --git a/src/gl/rwgl3.h b/src/gl/rwgl3.h index f6e5b3bd..4b138ac0 100644 --- a/src/gl/rwgl3.h +++ b/src/gl/rwgl3.h @@ -98,6 +98,7 @@ struct InstanceDataHeader : rw::InstanceDataHeader struct Shader; extern Shader *defaultShader, *defaultShader_noAT; +extern Shader *defaultShader_fullLight, *defaultShader_fullLight_noAT; struct Im3DVertex { diff --git a/src/gl/shaders/header.vert b/src/gl/shaders/header.vert index 025c2c41..bb9881f4 100644 --- a/src/gl/shaders/header.vert +++ b/src/gl/shaders/header.vert @@ -1,5 +1,5 @@ -#define DIRECTIONALS +//#define DIRECTIONALS //#define POINTLIGHTS //#define SPOTLIGHTS diff --git a/src/gl/shaders/header_vs.inc b/src/gl/shaders/header_vs.inc index ec9e505f..ffa46833 100644 --- a/src/gl/shaders/header_vs.inc +++ b/src/gl/shaders/header_vs.inc @@ -1,6 +1,6 @@ const char *header_vert_src = -"#define DIRECTIONALS\n" +"//#define DIRECTIONALS\n" "//#define POINTLIGHTS\n" "//#define SPOTLIGHTS\n"