Skip to content
Snippets Groups Projects
Select Git revision
  • 593a8adf5ac073d84781407981409a279429f606
  • master default protected
  • v0.5
  • v0.4b
  • v0.3b
  • v0.2b
  • v0.1b
7 results

Material.cpp

Blame
  • Material.cpp 14.04 KiB
    ////////////////////////////////////////////////////////////////////////////////
    //Copyright 2014 Andrew Cohen, Eric Wait, and Mark Winter
    //This file is part of LEVER 3-D - the tool for 5-D stem cell segmentation,
    //tracking, and lineaging. See http://bioimage.coe.drexel.edu 'software' section
    //for details. LEVER 3-D is free software: you can redistribute it and/or modify
    //it under the terms of the GNU General Public License as published by the Free
    //Software Foundation, either version 3 of the License, or (at your option) any
    //later version.
    //LEVER 3-D is distributed in the hope that it will be useful, but WITHOUT ANY
    //WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
    //A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
    //You should have received a copy of the GNU General Public License along with
    //LEVer in file "gnu gpl v3.txt".  If not, see  <http://www.gnu.org/licenses/>.
    ////////////////////////////////////////////////////////////////////////////////
    
    #include "Material.h"
    
    const Vec<float> StaticVolumeTextureMaterial::colors[6] = 
    {
    	Vec<float>(1.0f, 0.0f, 0.0f),
    	Vec<float>(0.0f, 1.0f, 0.0f),
    	Vec<float>(0.0f, 0.0f, 1.0f),
    	Vec<float>(1.0f, 1.0f, 0.0f),
    	Vec<float>(0.0f, 1.0f, 1.0f),
    	Vec<float>(1.0f, 0.0f, 1.0f)
    };
    
    
    void createStaticVolumeShaderText(std::string strChans);
    
    
    Material::Material(Renderer* rendererIn)
    {
    	renderer = rendererIn;
    	shaderIdx = -1;
    	wireframe = false;
    	cullBackFace = true;
    	testDepth = true;
    }
    
    Material::~Material()
    {
    	renderer = NULL;
    	shaderIdx = -1;
    	wireframe = false;
    }
    
    void Material::setWireframe(bool wireframe)
    {
    	this->wireframe = wireframe;
    }
    
    void Material::setShader(const std::string& shaderFilename, const std::string& shaderFunction, const std::string& shaderParams)
    {
    	shaderIdx = renderer->getPixelShader(shaderFilename,shaderFunction,shaderParams);
    }
    
    
    
    SingleColoredMaterial::SingleColoredMaterial(Renderer* rendererIn) : Material(rendererIn)
    {
    	colorBuffer.color = DirectX::XMFLOAT4(1,1,1,1);
    	colorBuffer.colorModifier = DirectX::XMFLOAT4(1,1,1,1);
    
    	renderer->createConstantBuffer(sizeof(ColorBuffer), &constBuffer);
    
    	setShader("DefaultMeshShaders.fx","DefaultMeshPixelShader","");
    }
    
    SingleColoredMaterial::SingleColoredMaterial(Renderer* rendererIn, Vec<float> colorIn) : Material(rendererIn)
    {
    	colorBuffer.color = DirectX::XMFLOAT4(colorIn.x,colorIn.y,colorIn.z,1);
    	colorBuffer.colorModifier = DirectX::XMFLOAT4(1,1,1,1);
    
    	renderer->createConstantBuffer(sizeof(ColorBuffer), &constBuffer);
    
    	setShader("DefaultMeshShaders.fx","DefaultMeshPixelShader","");
    }
    
    SingleColoredMaterial::SingleColoredMaterial(Renderer* rendererIn, Vec<float> colorIn, float alpha) : Material(rendererIn)
    {
    	colorBuffer.color = DirectX::XMFLOAT4(colorIn.x,colorIn.y,colorIn.z,alpha);
    	colorBuffer.colorModifier = DirectX::XMFLOAT4(1,1,1,1);
    
    	renderer->createConstantBuffer(sizeof(ColorBuffer), &constBuffer);
    
    	setShader("DefaultMeshShaders.fx","DefaultMeshPixelShader","");
    }
    
    SingleColoredMaterial::~SingleColoredMaterial()
    {
    	SAFE_RELEASE(constBuffer);
    
    	Material::~Material();
    }
    
    void SingleColoredMaterial::setColor(Vec<float> colorIn, float alpha)
    {
    	colorBuffer.color = DirectX::XMFLOAT4(colorIn.x,colorIn.y,colorIn.z,alpha);
    }
    
    void SingleColoredMaterial::setColorModifier(Vec<float> colorMod, float alphaMod)
    {
    	colorBuffer.colorModifier = DirectX::XMFLOAT4(colorMod.x,colorMod.y,colorMod.z,alphaMod);
    }
    
    void SingleColoredMaterial::setShaderResources()
    {
    	renderer->setPixelShaderConsts(constBuffer);
    }
    
    void SingleColoredMaterial::updateParams()
    {
    	renderer->updateShaderParams(&colorBuffer,constBuffer);
    }
    
    
    
    StaticVolumeTextureMaterial::StaticVolumeTextureMaterial(Renderer* rendererIn, Vec<size_t> dimsIn, int numChannelsIn, unsigned char* image,
    														 unsigned char* shaderConstMemoryIn/*=NULL*/) : Material(rendererIn)
    {
    	numChannels = numChannelsIn;
    	dims = dimsIn;
    	shaderConstMemory = shaderConstMemoryIn;
    
    	cullBackFace = false;
    	testDepth = false;
    	wireframe = false;
    	lightingOn = false;
    	attenuationOn = false;
    
    	char cBuffer[3];
    	sprintf_s(cBuffer,"%d",numChannels);
    	std::string strChans = cBuffer;
    	createStaticVolumeShaderText(strChans);
    
    	volPixShaderConsts.channelColors.resize(numChannels);
    	volPixShaderConsts.ranges.resize(numChannels);
    	volPixShaderConsts.transferFunctions.resize(numChannels);
    
    	if (shaderConstMemory==NULL)
    		shaderConstMemory = new unsigned char[volPixShaderConsts.sizeOf()];
    
    	renderer->createConstantBuffer(volPixShaderConsts.sizeOf(),&constBuffer);
    
    	setShader("StaticVolumePixelShader.fx","MultiChanVolumePixelShader",strChans);
    
    	samplerState.resize(numChannels);
    	shaderResourceView.resize(numChannels);
    
    	for (int i=0; i<numChannels; ++i)
    	{
    		samplerState[i] = renderer->getSamplerState();
    		shaderResourceView[i] = renderer->createTextureResourceView(dims, image + dims.product()*i);
    		setTransferFunction(i,Vec<float>(0.0f,1.0f,0.0f));
    		setRange(i,Vec<float>(0.0f,1.0f,0.0f));
    		setColor(i,colors[i%6],1.0f);
    		setAttenuationOn(false);
    		setLightOn(false);
    	}
    }
    
    StaticVolumeTextureMaterial::~StaticVolumeTextureMaterial()
    {
    	for (int i=0; i<numChannels; ++i)
    	{
    		SAFE_RELEASE(shaderResourceView[i]);
    	}
    
    	SAFE_RELEASE(constBuffer);
    
    	//delete[] shaderConstMemory;  //TODO make a better structure that cleans this up
    
    	Material::~Material();
    }
    
    void StaticVolumeTextureMaterial::setTransferFunction(int channel, Vec<float> transferFunction)
    {
    	//channel number of float4s before it
    	size_t memStart = channel*sizeof(float)*4;
    
    	memcpy((void*)(shaderConstMemory+memStart),&(transferFunction),sizeof(float)*3);
    }
    
    void StaticVolumeTextureMaterial::setRange(int channel, Vec<float> ranges)
    {
    	//channel number of float4 before it along with numChannel float4s behind that
    	size_t memStart = channel*sizeof(float)*4 + sizeof(float)*4*numChannels;
    
    	memcpy((void*)(shaderConstMemory+memStart),&(ranges),sizeof(float)*3);
    }
    
    void StaticVolumeTextureMaterial::setColor(int channel, Vec<float> color, float alphaMod)
    {
    	//channel number of float4 before it along with 2 times numchannel float4s behind that
    	size_t memStart = channel*sizeof(float)*4 + 8*sizeof(float)*numChannels;
    
    	memcpy((void*)(shaderConstMemory+memStart),&(color.x),sizeof(float)*3);
    	memcpy((void*)(shaderConstMemory+memStart+sizeof(float)*3),&(alphaMod),sizeof(float));
    }
    
    void StaticVolumeTextureMaterial::setLightOn(bool on)
    {
    	lightingOn = on;
    
    	float isOn = (on==true) ? (1.0f) : (0.0f);
    	//3 float4s along with 3 times numchannel float4s behind
    	size_t memStart = 12*sizeof(float)+12*sizeof(float)*numChannels;
    
    	memcpy((void*)(shaderConstMemory+memStart),&isOn,sizeof(float));
    }
    
    void StaticVolumeTextureMaterial::setAttenuationOn(bool on)
    {
    	attenuationOn = on;
    
    	float isOn = (on == true) ? (1.0f) : (0.0f);
    	//2nd float plus 3 float4s along with 3 times numchannel float4s behind
    	size_t memStart = sizeof(float) + 12 * sizeof(float) + 12 * sizeof(float)*numChannels;
    
    	memcpy((void*)(shaderConstMemory + memStart), &isOn, sizeof(float));
    }
    
    
    void StaticVolumeTextureMaterial::setGradientSampleDir(Vec<float> xDir, Vec<float> yDir, Vec<float> zDir)
    {
    	//3 times numchannel float4s behind
    	size_t memStart = 12*sizeof(float)*numChannels;
    
    	memcpy((void*)(shaderConstMemory+memStart),&xDir,sizeof(float)*3);
    	memcpy((void*)(shaderConstMemory+memStart+sizeof(float)*4),&yDir,sizeof(float)*3);
    	memcpy((void*)(shaderConstMemory+memStart+sizeof(float)*8),&zDir,sizeof(float)*3);
    }
    
    void StaticVolumeTextureMaterial::updateParams()
    {
    	renderer->updateShaderParams(shaderConstMemory,constBuffer);
    }
    
    void StaticVolumeTextureMaterial::setShaderResources()
    {
    	renderer->setPixelShaderConsts(constBuffer);
    	renderer->setPixelShaderResourceViews(0,(int)shaderResourceView.size(),shaderResourceView.data());
    	renderer->setPixelShaderTextureSamplers(0,(int)samplerState.size(),samplerState.data());
    }
    
    void createStaticVolumeShaderText(std::string strChans)
    {
    	std::string shaderText = "";
    
    	shaderText += "///////////////////////////////////////////////////////////////////////////////\n";
    	shaderText += "// Copyright 2014 Andrew Cohen, Eric Wait, and Mark Winter\n";
    	shaderText += "// This file is part of LEVER 3-D - the tool for 5-D stem cell segmentation,\n";
    	shaderText += "// tracking, and lineaging. See http://bioimage.coe.drexel.edu 'software' section\n";
    	shaderText += "// for details. LEVER 3-D is free software: you can redistribute it and/or modify\n";
    	shaderText += "// it under the terms of the GNU General Public License as published by the Free\n";
    	shaderText += "// Software Foundation, either version 3 of the License, or (at your option) any\n";
    	shaderText += "// later version.\n";
    	shaderText += "// LEVER 3-D is distributed in the hope that it will be useful, but WITHOUT ANY\n";
    	shaderText += "// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR\n";
    	shaderText += "// A PARTICULAR PURPOSE.  See the GNU General Public License for more details.\n";
    	shaderText += "// You should have received a copy of the GNU General Public License along with\n";
    	shaderText += "// LEVer in file \"gnu gpl v3.txt\".  If not, see  <http://www.gnu.org/licenses/>.\n";
    	shaderText += "///////////////////////////////////////////////////////////////////////////////\n";
    	shaderText += "\n";
    	shaderText += "cbuffer ConstantPSBuffer : register( b1 )\n";
    	shaderText += "{\n";
    	shaderText += "	float4 transferFunctions[" + strChans + "];\n";
    	shaderText += "	float4 ranges[" + strChans + "];\n";
    	shaderText += "	float4 channelColor[" + strChans + "];\n";
    	shaderText += "	float4 gradientSampleDirection[3];\n";
    	shaderText += "	float4 lightOn;\n";
    	shaderText += "};\n";
    	shaderText += "\n";
    	shaderText += "struct PixelOutputType\n";
    	shaderText += "{\n";
    	shaderText += "\tfloat4 color : SV_TARGET;\n";
    	shaderText += "\tfloat depth : SV_DEPTH;\n";
    	shaderText += "};\n";
    	shaderText += "\n";
    	shaderText += "Texture3D    g_txDiffuse[" + strChans + "] : register( t0 );\n";
    	shaderText += "SamplerState g_samLinear[" + strChans + "] : register( s0 );\n";
    	shaderText += "\n";
    	shaderText += "struct VS_OUTPUT\n";
    	shaderText += "{\n";
    	shaderText += "\tfloat4 Pos : SV_POSITION;\n";
    	shaderText += "\tfloat3 TextureUV : TEXCOORD0;\n";
    	shaderText += "\tfloat3 Normal : NORMAL;\n";
    	shaderText += "\tfloat3 Dpth : TEXCOORD1;\n";
    	shaderText += "};\n";
    	shaderText += "\n";
    	shaderText += "PixelOutputType MultiChanVolumePixelShader( VS_OUTPUT input )\n";
    	shaderText += "{\n";
    	shaderText += "\tPixelOutputType output = (PixelOutputType)0;\n";
    	shaderText += "\tfloat alpha = 0.0f;\n";
    	shaderText += "\n";
    	shaderText += "\tfloat4 mainLightDir = float4(-0.5774,-0.5774,0.5774,0);\n";
    	shaderText += "\tfloat3 unlitComposite = float3(0.0f,0.0f,0.0f);\n";
    	shaderText += "\tfloat3 alphaComposite = float3(0.0f,0.0f,0.0f);\n";
    	shaderText += "\n";
    	shaderText += "\tint numAlpha = 0;\n";
    	shaderText += "\tfloat3 grad;\n";
    	shaderText += "\n";
    	shaderText += "float maxIntensity = 0;\n";
    	shaderText += "\n";
    	shaderText += "\t[unroll(" + strChans + ")] for (int i=0; i<" + strChans + "; ++i)\n";
    	shaderText += "\t{\n";
    	shaderText += "\t\tfloat intensity = g_txDiffuse[i].Sample( g_samLinear[i], input.TextureUV );\n";
    	shaderText += "\t\tintensity = clamp(intensity,ranges[i][0],ranges[i][1]);\n";
    	shaderText += "\t\tintensity = transferFunctions[i][0]*intensity*intensity+transferFunctions[i][1]*intensity+transferFunctions[i][2];\n";
    	shaderText += "\t\tif (intensity < 0.2f || channelColor[i].a < 0.01f)\n";
    	shaderText += "\t\t{\n";
    	shaderText += "\t\t\tintensity = 0;\n";
    	shaderText += "\t\t}\n";
    	//shaderText += "\t\tmaxIntensity = max(intensity*channelColor[i].a,maxIntensity);\n";
    	shaderText += "\t\tmaxIntensity = max(intensity,maxIntensity);\n";
    	shaderText += "\n";
    	shaderText += "\t\tfloat lightMod = 1.0f;\n";
    	shaderText += "\t\tif(lightOn.x>0)\n";
    	shaderText += "\t\t{\n";
    	shaderText += "\t\t\tgrad.x = g_txDiffuse[i].Sample(g_samLinear[i], input.TextureUV+gradientSampleDirection[0]) - \n";
    	shaderText += "\t\t\t\tg_txDiffuse[i].Sample(g_samLinear[i], input.TextureUV-gradientSampleDirection[0]);\n";
    	shaderText += "\t\t\tgrad.y = g_txDiffuse[i].Sample(g_samLinear[i], input.TextureUV+gradientSampleDirection[1]) - \n";
    	shaderText += "\t\t\t\tg_txDiffuse[i].Sample(g_samLinear[i], input.TextureUV-gradientSampleDirection[1]);\n";
    	shaderText += "\t\t\tgrad.z = g_txDiffuse[i].Sample(g_samLinear[i], input.TextureUV+gradientSampleDirection[2]) - \n";
    	shaderText += "\t\t\t\tg_txDiffuse[i].Sample(g_samLinear[i], input.TextureUV-gradientSampleDirection[2]);\n";
    	shaderText += "\t\t\tgrad = normalize(grad);\n";
    	shaderText += "\t\t\tlightMod = saturate(dot(grad,mainLightDir)*2.0)*0.65 + 0.35;\n";
    	shaderText += "\t\t}\n";
    	shaderText += "\n";
    	shaderText += "\t\toutput.color.rgb += (lightMod*intensity*channelColor[i].rgb);\n";
    	shaderText += "\t\tunlitComposite += intensity*channelColor[i].rgb;\n";
    	shaderText += "\t\talphaComposite += intensity*channelColor[i].rgb*channelColor[i].a;\n";
    	shaderText += "\t}\n";
    	shaderText += "\n";
    	shaderText += "\tfloat maxComponent = max(max(unlitComposite.r,unlitComposite.g),unlitComposite.b);\n";
    	shaderText += "\tfloat maxAplha = max(max(alphaComposite.r,alphaComposite.g),alphaComposite.b);\n";
    	shaderText += "\tif (maxComponent!=0)\n";
    	shaderText += "\t{\n";
    	shaderText += "\t\toutput.color.rgb /= maxComponent;\n";
    	shaderText += "\t\toutput.color.rgb *= maxIntensity;\n";
    	shaderText += "\t}\n";
    	shaderText += "\tif (maxAplha!=0)\n";
    	shaderText += "\t{\n";
    	shaderText += "\t\toutput.color.a = maxAplha;\n";
    	shaderText += "\t}else{\n";
    	shaderText += "\t\toutput.color.a = 0;\n";
    	shaderText += "\t}\n";
    	shaderText += "\n";
    	shaderText += "\n";
    	shaderText += "\tif(lightOn.y>0)\n";
    	shaderText += "\t{\n";
    	shaderText += "\t\tfloat distMult = (input.Dpth.z<=0) ? (1) : (1-input.Dpth.z);\n";
    	shaderText += "\t\toutput.color.r *= distMult;\n";
    	shaderText += "\t\toutput.color.g *= distMult;\n";
    	shaderText += "\t\toutput.color.b *= distMult;\n";
    	shaderText += "\t\toutput.color.a *= distMult;\n";
    	shaderText += "\t}\n";
    	shaderText += "\n";
    	shaderText += "\toutput.depth = 1.0f;\n";
    	shaderText += "\n";
    	shaderText += "\treturn output;\n";
    	shaderText += "}\n";
    
    	FILE* file;
    	fopen_s(&file,"StaticVolumePixelShader.fx","w");
    
    	fprintf(file,shaderText.c_str());
    
    	fclose(file);
    }