Serious-Engine/Sources/Shaders/MultiLayerShader.cpp
2016-03-11 15:57:17 +02:00

137 lines
3.7 KiB
C++

/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "StdH.h"
#define TEXTURE_COUNT 2
#define UVMAPS_COUNT 2
#define COLOR_COUNT 2
#define FLOAT_COUNT 2
#define FLAGS_COUNT 2
#define LAYER0_TEXTURE 0
#define LAYER0_UVMAP 0
#define LAYER0_COLOR 0
#define LAYER0_TILING 0
#define LAYER1_TEXTURE 1
#define LAYER1_UVMAP 1
#define LAYER1_COLOR 1
#define LAYER1_TILING 1
#define BASE_DOUBLE_SIDED (1UL<<0) // Double sided
#define BASE_FULL_BRIGHT (1UL<<1) // Full bright
SHADER_MAIN(MultiLayer)
{
// this will be reused for all layers
FLOAT fLayerTiling = 1.0f;
// do 0th layer pass - base layer
shaSetTexture(LAYER0_TEXTURE);
shaSetTextureWrapping( GFX_REPEAT, GFX_REPEAT);
shaSetUVMap(LAYER0_UVMAP);
shaSetColor(LAYER0_COLOR);
shaEnableDepthTest();
shaDepthFunc(GFX_LESS_EQUAL);
COLOR &colModelColor = shaGetModelColor();
BOOL bDoubleSided = shaGetFlags()&BASE_DOUBLE_SIDED;
BOOL bOpaque = (colModelColor&0xFF)==0xFF;
if(bDoubleSided) {
shaCullFace(GFX_NONE);
} else {
shaCullFace(GFX_BACK);
}
shaCalculateLight();
// if fully opaque
if(bOpaque) {
// shaEnableAlphaTest(TRUE);
shaDisableBlend();
shaEnableDepthWrite();
// if translucent
} else {
// shaEnableAlphaTest(FALSE);
shaEnableBlend();
shaBlendFunc(GFX_SRC_ALPHA, GFX_INV_SRC_ALPHA);
shaDisableDepthWrite();
shaModifyColorForFog();
}
if(shaOverBrightningEnabled()) shaSetTextureModulation(2);
fLayerTiling = shaGetFloat(LAYER0_TILING);
if (fLayerTiling!=1.0f) {
GFXTexCoord *ptxcOld = shaGetUVMap(LAYER0_UVMAP);
GFXTexCoord *ptxcNew = shaGetNewTexCoordArray();
INDEX ctTexCoords = shaGetVertexCount();
if(ctTexCoords>0 && ptxcOld!=NULL) {
for(INDEX itxc=0;itxc<ctTexCoords;itxc++)
{
ptxcNew[itxc].u = ptxcOld[itxc].u * fLayerTiling;
ptxcNew[itxc].v = ptxcOld[itxc].v * fLayerTiling;
}
shaSetTexCoords(ptxcNew);
}
}
shaRender();
if(bOpaque) {
shaDoFogPass();
}
// do 1st layer pass
fLayerTiling = shaGetFloat(LAYER1_TILING);
shaBlendFunc( GFX_SRC_ALPHA, GFX_INV_SRC_ALPHA);
shaSetTexture(LAYER1_TEXTURE);
shaSetUVMap(LAYER1_UVMAP);
shaSetColor(LAYER1_COLOR);
shaCalculateLight();
shaEnableBlend();
if (fLayerTiling!=1.0f) {
GFXTexCoord *ptxcOld = shaGetUVMap(LAYER1_UVMAP);
GFXTexCoord *ptxcNew = shaGetNewTexCoordArray();
INDEX ctTexCoords = shaGetVertexCount();
if(ctTexCoords>0 && ptxcOld!=NULL) {
for(INDEX itxc=0; itxc<ctTexCoords; itxc++)
{
ptxcNew[itxc].u = ptxcOld[itxc].u * fLayerTiling;
ptxcNew[itxc].v = ptxcOld[itxc].v * fLayerTiling;
}
shaSetTexCoords(ptxcNew);
}
}
shaRender();
shaDisableBlend();
if(shaOverBrightningEnabled()) shaSetTextureModulation(1);
}
SHADER_DESC(MultiLayer, ShaderDesc &shDesc)
{
shDesc.sd_astrTextureNames .New(TEXTURE_COUNT);
shDesc.sd_astrTexCoordNames.New(UVMAPS_COUNT);
shDesc.sd_astrColorNames .New(COLOR_COUNT);
shDesc.sd_astrFloatNames .New(FLOAT_COUNT);
shDesc.sd_astrFlagNames .New(FLAGS_COUNT);
// layer 0 - base
shDesc.sd_astrTextureNames [0] = "Layer0* texture";
shDesc.sd_astrTexCoordNames[0] = "Layer0* UVMap";
shDesc.sd_astrColorNames [0] = "Layer0* color";
shDesc.sd_astrFloatNames [0] = "Layer0* tiling factor";
// layer 1
shDesc.sd_astrTextureNames [1] = "Layer1 texture";
shDesc.sd_astrTexCoordNames[1] = "Layer1 UVMap";
shDesc.sd_astrColorNames [1] = "Layer1 color";
shDesc.sd_astrFloatNames [1] = "Layer1 tiling factor";
shDesc.sd_astrFlagNames[0] = "Double sided";
shDesc.sd_astrFlagNames[1] = "Full bright";
shDesc.sd_strShaderInfo = "Multi Layer shader";
}