GL3: Initial lightmap shader implementation

--HG--
branch : opengl3
hg/feature/opengl3
kaetemi 11 years ago
parent 9df1935f5e
commit 181db9adb9

@ -482,6 +482,9 @@ bool CDriverGL3::setupMaterial(CMaterial& mat)
// =====================
switch (matShader)
{
case CMaterial::LightMap:
// Programs are setup in multipass
return true;
default:
return setupBuiltinPrograms();
}
@ -668,22 +671,21 @@ void CDriverGL3::setupLightMapPass(uint pass)
const CMaterial &mat= *_CurrentMaterial;
// common colors
static uint32 packedColorBlack= CRGBA(0,0,0,255).getPacked();
static GLfloat glcolBlack[4]= {0.f,0.f,0.f,1.f};
static uint32 packedColorWhite= CRGBA(255,255,255,255).getPacked();
static GLfloat glcolWhite[4]= {1.f,1.f,1.f,1.f};
static uint32 packedColorGrey= CRGBA(128,128,128,128).getPacked();
static GLfloat glcolGrey[4]= {0.5f,0.5f,0.5f,1.f};
static const GLfloat glcolBlack[4] = { 0.f, 0.f, 0.f, 1.f };
static const GLfloat glcolWhite[4] = { 1.f, 1.f, 1.f, 1.f };
static const GLfloat glcolGrey[4] = { 0.5f, 0.5f, 0.5f, 1.f };
// No lightmap or all blacks??, just setup "black texture" for stage 0.
if (_NLightMaps == 0)
{
nldebug("No lightmaps");
ITexture *text = mat.getTexture(0);
activateTexture(0, text);
// setup std modulate env
// CMaterial::CTexEnv env;
//activateTexEnvMode(0, env); // FIXME GL3
// activateTexEnvMode(0, env); // FIXME GL3: standard modulate env
// Since Lighting is disabled, as well as colorArray, must setup alpha.
// setup color to 0 => blackness. in emissive cause texture can still be lighted by dynamic light
@ -691,7 +693,7 @@ void CDriverGL3::setupLightMapPass(uint pass)
// FIXME GL3 LIGHTMAP
// Setup gen tex off
// setTexGenModeVP(0, TexGenDisabled); // FIXME GL3
setTexGenModeVP(0, TexGenDisabled);
// And disable other stages.
for (uint stage = 1; stage < IDRV_MAT_MAXTEXTURES; stage++)
@ -700,6 +702,9 @@ void CDriverGL3::setupLightMapPass(uint pass)
activateTexture(stage, NULL);
}
// Setup the programs now
setupBuiltinPrograms();
return;
}
@ -711,16 +716,15 @@ void CDriverGL3::setupLightMapPass(uint pass)
uint nstages;
lmapId = pass * _NLightMapPerPass; // Nb lightmaps already processed
// N lightmaps for this pass, plus the texture.
nstages= std::min(_NLightMapPerPass, _NLightMaps-lmapId) + 1;
nstages = std::min(_NLightMapPerPass, _NLightMaps - lmapId) + 1; // at most 4
// For LMC (lightmap 8Bit compression) compute the total AmbientColor in vertex diffuse
// need only if standard MulADD version
{
uint32 r = 0;
uint32 g = 0;
uint32 b = 0;
// sum only the ambient of lightmaps that will be drawn this pass
for (uint sa=0;sa<nstages-1;sa++)
for (uint sa = 0; sa < nstages - 1; ++sa)
{
uint wla = _LightMapLUT[lmapId + sa];
// must mul them by their respective mapFactor too
@ -735,18 +739,17 @@ void CDriverGL3::setupLightMapPass(uint pass)
b = std::min(b, (uint32)255);
// this color will be added to the first lightmap (with help of emissive)
// CRGBA col((uint8)r,(uint8)g,(uint8)b,255);
// GLfloat glcol[4];
// convColor(col, glcol);
// _DriverGLStates.setEmissive(col.getPacked(), glcol);
// FIXME GL3 LIGHTMAP
}
CRGBA col((uint8)r,(uint8)g,(uint8)b,255);
// Lightmap factors
NLMISC::CRGBAF selfIllumination(col);
NLMISC::CRGBAF constant[IDRV_MAT_MAXTEXTURES];
// setup all stages.
for (uint stage= 0; stage<IDRV_MAT_MAXTEXTURES; stage++)
for (uint stage = 0; stage < IDRV_MAT_MAXTEXTURES; ++stage)
{
// if must setup a lightmap stage.
if (stage<nstages-1)
// if must setup a lightmap stage
if (stage < nstages - 1) // last stage is user texture
{
// setup lightMap.
uint whichLightMap = _LightMapLUT[lmapId];
@ -767,12 +770,16 @@ void CDriverGL3::setupLightMapPass(uint pass)
//==================================================
if (text)
{
static CMaterial::CTexEnv stdEnv;
// Setup env for texture stage.
setTexGenModeVP(stage, TexGenDisabled);
{
// Here, we are sure that texEnvCombine4 or texEnvCombine3 is OK.
// nlassert(_Extensions.ATITextureEnvCombine3);
// FIXME GL3: builtin TexEnv[stage] = TexEnvSpecialLightMap
// Setup constant color with Lightmap factor.
constant[stage] = NLMISC::CRGBAF(lmapFactor);
/*static CMaterial::CTexEnv stdEnv;
{
// setup constant color with Lightmap factor.
stdEnv.ConstantColor = lmapFactor;
@ -786,16 +793,13 @@ void CDriverGL3::setupLightMapPass(uint pass)
// activateTexEnvColor(stage, stdEnv); // FIXME GL3
// Setup env for texture stage.
// setTexGenModeVP(stage, TexGenDisabled); // FIXME GL3
// setup TexEnvCombine4 (ignore alpha part).
/*if (_CurrentTexEnvSpecial[stage] != TexEnvSpecialLightMap)
{
// TexEnv is special.
_CurrentTexEnvSpecial[stage] = TexEnvSpecialLightMap;
}*/ // FIXME GL3
}
/*}*/
}
// Next lightmap.
@ -812,10 +816,10 @@ void CDriverGL3::setupLightMapPass(uint pass)
activateTexture(stage, text);
// setup ModulateRGB/ReplaceAlpha env. (this may disable possible COMBINE4_NV setup).
// activateTexEnvMode(stage, _LightMapLastStageEnv); // FIXME GL3
// activateTexEnvMode(stage, _LightMapLastStageEnv); // SHADER BUILTIN
// Setup gen tex off
// setTexGenModeVP(stage, TexGenDisabled); // FIXME GL3
setTexGenModeVP(stage, TexGenDisabled);
}
}
else
@ -894,6 +898,22 @@ void CDriverGL3::setupLightMapPass(uint pass)
// _DriverGLStates.setDiffuse(packedColorBlack, glcolBlack);
// FIXME GL3 LIGHTMAP
}
// Setup the programs now
setupBuiltinPrograms();
// Set constants
for (uint stage = 0; stage < IDRV_MAT_MAXTEXTURES; ++stage)
{
uint constantIdx = m_DriverPixelProgram->getUniformIndex(CProgramIndex::TName(CProgramIndex::Constant0 + stage));
if (constantIdx != ~0)
{
setUniform4f(IDriver::PixelProgram, constantIdx, constant[stage].R, constant[stage].G, constant[stage].B, constant[stage].A);
}
}
// Set self illumination
// FIXME GL3: selfIllumination
}
// ***************************************************************************

@ -341,11 +341,39 @@ void ppSpecular(std::stringstream &ss, const CPPBuiltin &desc)
}
else
{
nlwarning("No textures defined in Specular shader");
nlwarning("PP: No textures defined in Specular shader");
// do nothing
}
}
void ppLightmap(std::stringstream &ss, const CPPBuiltin &desc)
{
uint nstages;
for (nstages = 0; nstages < IDRV_MAT_MAXTEXTURES; ++nstages)
if (!useTex(desc, nstages))
break;
if (nstages == 0)
{
// do nothing
nlwarning("PP: Lightmap without textures setup");
}
else if (nstages == 1)
{
// single map (doesn't support alpha)
nlwarning("PP: Lightmap material without lightmaps setup %i %i %i %i", useTex(desc, 0), useTex(desc, 1), useTex(desc, 2), useTex(desc, 3));
ss << "fragColor = vec4(1.0, 1.0, 1.0, 1.0);" << std::endl; // HACK FIXME GL3
ss << "fragColor = texel" << (nstages - 1) << " * fragColor;" << std::endl;
}
else
{
ss << "fragColor = vec4(1.0, 1.0, 1.0, 1.0);" << std::endl; // HACK FIXME GL3
ss << "vec4 lightmapop = vec4(0.0, 0.0, 0.0, 0.0);" << std::endl;
for (uint stage = 0; stage < (nstages - 1); ++stage)
ss << "lightmapop = lightmapop + texel" << stage << " * constant" << stage << " * texel" << (nstages - 1) << ";" << std::endl;
ss << "fragColor = fragColor * lightmapop;" << std::endl;
}
}
void ppGenerate(std::string &result, const CPPBuiltin &desc)
{
std::stringstream ss;
@ -452,7 +480,15 @@ void ppGenerate(std::string &result, const CPPBuiltin &desc)
else if (useTex(desc, stage))
{
ss << "vec4 texel" << stage << " = texture(sampler" << stage << ", ";
if (hasFlag(desc.VertexFormat, g_VertexFlags[TexCoord0 + stage]))
if (desc.Shader == CMaterial::LightMap && stage != (maxTex - 1) && hasFlag(desc.VertexFormat, g_VertexFlags[TexCoord1]))
{
ss << g_AttribNames[TexCoord1];
}
else if (desc.Shader == CMaterial::LightMap && hasFlag(desc.VertexFormat, g_VertexFlags[TexCoord0]))
{
ss << g_AttribNames[TexCoord0];
}
else if (hasFlag(desc.VertexFormat, g_VertexFlags[TexCoord0 + stage]))
{
ss << g_AttribNames[TexCoord0 + stage];
}
@ -479,6 +515,9 @@ void ppGenerate(std::string &result, const CPPBuiltin &desc)
case CMaterial::Specular:
ppSpecular(ss, desc);
break;
case CMaterial::LightMap:
ppLightmap(ss, desc);
break;
default:
nlwarning("GL3: Try to generate unknown shader type (%s)", s_ShaderNames[desc.Shader]);
// ss << "fragColor = vec(1.0, 0.0, 0.5, 1.0);" << std::endl;
@ -559,6 +598,41 @@ void CPPBuiltin::checkDriverStateTouched(CDriverGL3 *driver) // MUST NOT depend
}
}
void CPPBuiltin::checkDriverMaterialStateTouched(CDriverGL3 *driver, CMaterial &mat)
{
CMaterial::TShader shader = getSupportedShader(mat.getShader());
switch (shader)
{
case CMaterial::LightMap:
// Use Textures from current driver state
// NB: Might be necessary to use this for every material type and remove the one from the other function
uint maxTex = maxTextures(shader);
uint8 textureActive = 0x00;
for (uint stage = 0; stage < maxTex; ++stage)
{
NL3D::ITexture *tex = driver->_CurrentTexture[stage];
if (tex)
{
textureActive |= (1 << stage);
uint8 texSamplerMode = tex->isTextureCube() ? SamplerCube : Sampler2D;
if (TexSamplerMode[stage] != texSamplerMode)
{
TexSamplerMode[stage] = texSamplerMode;
Touched = true;
}
}
}
if (TextureActive != textureActive)
{
TextureActive = textureActive;
Touched = true;
}
// nldebug("TextureActive: %i", TextureActive);
break;
}
}
void CPPBuiltin::checkMaterialStateTouched(CMaterial &mat) // MUST NOT depend on any state set by checkDriverStateTouched
{
// Optimize
@ -582,6 +656,11 @@ void CPPBuiltin::checkMaterialStateTouched(CMaterial &mat) // MUST NOT depend on
uint maxTex = maxTextures(shader);
if (touched & IDRV_TOUCHED_ALLTEX) // Note: There is a case where textures are provided where no texture coordinates are provided, this is handled gracefully by the pixel program generation (it will use a vec(0) texture coordinate). The inverse is an optimization issue
{
switch (shader)
{
case CMaterial::LightMap:
default:
// Use textures directly from the CMaterial
uint8 textureActive = 0x00;
for (uint stage = 0; stage < maxTex; ++stage)
{
@ -604,6 +683,8 @@ void CPPBuiltin::checkMaterialStateTouched(CMaterial &mat) // MUST NOT depend on
TextureActive = textureActive;
Touched = true;
}
break;
}
}
if (useTexEnv(shader) && (touched & IDRV_TOUCHED_TEXENV))
{

@ -667,6 +667,7 @@ bool CDriverGL3::setupBuiltinPixelProgram()
nlassert(matDrv);
matDrv->PPBuiltin.checkDriverStateTouched(this);
matDrv->PPBuiltin.checkDriverMaterialStateTouched(this, mat);
matDrv->PPBuiltin.checkMaterialStateTouched(mat);
if (matDrv->PPBuiltin.Touched)

@ -73,6 +73,7 @@ struct CPPBuiltin
bool Touched;
void checkDriverStateTouched(CDriverGL3 *driver);
void checkDriverMaterialStateTouched(CDriverGL3 *driver, CMaterial &mat);
void checkMaterialStateTouched(CMaterial &mat);
};

Loading…
Cancel
Save