Skip to content
Snippets Groups Projects
Commit c8d79cfd authored by Michael Heyde's avatar Michael Heyde
Browse files

fixed formalizm of preintegration to the correct one

parent 710957bc
No related branches found
No related tags found
No related merge requests found
......@@ -9,7 +9,6 @@ import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.Map;
import bdv.jogl.VolumeRenderer.GLErrorHandler;
import bdv.jogl.VolumeRenderer.Scene.Texture;
import bdv.jogl.VolumeRenderer.ShaderPrograms.ShaderSources.ISourceListener;
......@@ -18,6 +17,7 @@ import bdv.jogl.VolumeRenderer.ShaderPrograms.ShaderSources.functions.accumulato
import bdv.jogl.VolumeRenderer.ShaderPrograms.ShaderSources.functions.accumulator.MaximumVolumeAccumulator;
import bdv.jogl.VolumeRenderer.TransferFunctions.TransferFunction1D;
import bdv.jogl.VolumeRenderer.TransferFunctions.TransferFunctionAdapter;
import bdv.jogl.VolumeRenderer.TransferFunctions.sampler.ITransferFunctionSampler;
import bdv.jogl.VolumeRenderer.utils.GeometryUtils;
import bdv.jogl.VolumeRenderer.utils.VolumeDataManager;
import bdv.jogl.VolumeRenderer.utils.VolumeDataManagerAdapter;
......@@ -54,8 +54,6 @@ public class MultiVolumeRenderer extends AbstractShaderSceneElement{
private TransferFunction1D tf;
private Texture colorTexture;
private boolean isColorUpdateable;
private boolean isEyeUpdateable = true;
......@@ -106,6 +104,8 @@ public class MultiVolumeRenderer extends AbstractShaderSceneElement{
private float[] slice2Dplane;
private ITransferFunctionSampler currentSampler;
public void setDrawRect(AABBox rect){
drawCubeTransformation = getTransformationRepresentAABBox(rect);
drawRect = rect;
......@@ -416,7 +416,7 @@ public class MultiVolumeRenderer extends AbstractShaderSceneElement{
diagVec[i]/=sizeDim;
}
length = VectorUtil.normVec3(diagVec);
length = runLength;//VectorUtil.normVec3(diagVec);
gl2.glUniform1f(getLocation(suvTransferFuntionSize), length);
GLErrorHandler.assertGL(gl2);
......@@ -626,12 +626,9 @@ public class MultiVolumeRenderer extends AbstractShaderSceneElement{
volumeTextureMap.put(i, t);
GLErrorHandler.assertGL(gl2);
}
location = getLocation(suvColorTexture);
colorTexture = new Texture(GL2.GL_TEXTURE_1D,location,GL2.GL_RGBA,GL2.GL_RGBA,GL2.GL_FLOAT);
colorTexture.genTexture(gl2);
colorTexture.setTexParameteri(gl2,GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR);
colorTexture.setTexParameteri(gl2, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR);
colorTexture.setTexParameteri(gl2, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP_TO_BORDER);
this.currentSampler = tf.getSampler();
currentSampler.init(gl2, getLocation(suvColorTexture));
}
@Override
......@@ -672,10 +669,12 @@ public class MultiVolumeRenderer extends AbstractShaderSceneElement{
}
//get Buffer last key is the highest number
FloatBuffer buffer = tf.getTexture(length/(float)samples);
//FloatBuffer buffer = tf.getTexture(length/(float)samples);
tf.getSampler().updateData(gl2,tf, length/(float)samples);
//upload data
colorTexture.update(gl2, 0, buffer, new int[]{buffer.capacity()/4});
//gl2.glBindTexture(GL2.GL_TEXTURE_1D, 0);
isColorUpdateable = false;
}
......@@ -698,6 +697,7 @@ public class MultiVolumeRenderer extends AbstractShaderSceneElement{
*/
public void setTransferFunction(final TransferFunction1D tf){
this.tf = tf;
this.tf.addTransferFunctionListener(new TransferFunctionAdapter() {
@Override
......@@ -736,8 +736,9 @@ public class MultiVolumeRenderer extends AbstractShaderSceneElement{
@Override
protected void disposeSubClass(GL4 gl2) {
colorTexture.delete(gl2);
currentSampler.dispose(gl2);
for(Texture texture: volumeTextureMap.values() ){
texture.delete(gl2);
}
......
......@@ -8,38 +8,13 @@ public class PreIntegrationInterpreter extends AbstractTransferFunctionInterpret
public String[] declaration() {
String dec[] ={
"#line "+Thread.currentThread().getStackTrace()[1].getLineNumber()+ " 10",
"uniform sampler1D "+suvColorTexture+";",
"const float minValue = 0.000001;",
"const float minValueHalf = minValue/2.0;",
"uniform sampler2D "+suvColorTexture+";",
"float texoffset = 1.0/(2.0*"+suvMaxVolumeValue+");",
"float texnorm = ("+suvMaxVolumeValue+"-1.0)/"+suvMaxVolumeValue+";",
"",
"vec4 "+getFunctionName()+"(float vbegin, float vend, float distance){",
" if(vbegin - vend < minValue){",
" if(vbegin - minValueHalf < 0.0){",
" vend+= minValue*10.0;",
" }else{",
" if(vend +minValueHalf > 1.0){",
" vbegin-=minValue*10.0;",
" }else{",
" vend+=minValueHalf*10.0;",
" vbegin-=minValueHalf*10.0;",
" }",
" }",
" }",
" vec4 iFront = texture("+suvColorTexture+",vbegin*texnorm + texoffset);",
" vec4 iBack = texture("+suvColorTexture+",vend*texnorm + texoffset);",
" vec4 color = vec4(0.0);",
" vec4 iDiff = distance/(vend - vbegin) * (iBack - iFront);",
"",
" //alpha desample",
" color.a = 1.0 - exp(-iDiff.a);",
"",
" //rgb desample",
" color.rgb = iDiff.rgb;",
" return color;",
"}",
""
" return texture("+suvColorTexture+",vec2(vbegin*texnorm + texoffset,vend*texnorm + texoffset)).rgba;",
"}"
};
return dec;
}
......
......@@ -353,9 +353,7 @@ public class TransferFunction1D {
fireColorChangedEventAll();
}
public FloatBuffer getTexture(float f){
return sampler.sample(this, f);
}
public IFunction getTransferFunctionShaderCode(){
return sampler.getShaderCode();
......
......@@ -2,6 +2,8 @@ package bdv.jogl.VolumeRenderer.TransferFunctions.sampler;
import java.nio.FloatBuffer;
import com.jogamp.opengl.GL4;
import bdv.jogl.VolumeRenderer.ShaderPrograms.ShaderSources.functions.IFunction;
import bdv.jogl.VolumeRenderer.TransferFunctions.TransferFunction1D;
......@@ -11,6 +13,15 @@ import bdv.jogl.VolumeRenderer.TransferFunctions.TransferFunction1D;
*
*/
public interface ITransferFunctionSampler {
public void init(GL4 gl, int colorTextureId);
public void dispose(GL4 gl);
public void updateData(GL4 gl,TransferFunction1D transferFunction, float sampleStep);
/**
* Retruns the desampling shader code
* @return
......
......@@ -2,18 +2,24 @@ package bdv.jogl.VolumeRenderer.TransferFunctions.sampler;
import java.awt.Color;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.TreeMap;
import com.jogamp.common.nio.Buffers;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GL4;
import bdv.jogl.VolumeRenderer.Scene.Texture;
import bdv.jogl.VolumeRenderer.ShaderPrograms.ShaderSources.functions.IFunction;
import bdv.jogl.VolumeRenderer.ShaderPrograms.ShaderSources.functions.transferfunctioninterpreter.PreIntegrationInterpreter;
import bdv.jogl.VolumeRenderer.TransferFunctions.TransferFunction1D;
import static bdv.jogl.VolumeRenderer.ShaderPrograms.ShaderSources.MultiVolumeRendererShaderSource.suvColorTexture;
import static bdv.jogl.VolumeRenderer.utils.WindowUtils.getNormalizedColor;
public class PreIntegrationSampler implements ITransferFunctionSampler {
private final PreIntegrationInterpreter desampler = new PreIntegrationInterpreter();
private Texture colorTexture;
@Override
public IFunction getShaderCode() {
......@@ -44,20 +50,40 @@ public class PreIntegrationSampler implements ITransferFunctionSampler {
return stepSize/2.f * (a1+a2);
}
@Override
public void init(GL4 gl, int colorTextureId) {
colorTexture = new Texture(GL2.GL_TEXTURE_2D,colorTextureId,GL2.GL_RGBA,GL2.GL_RGBA,GL2.GL_FLOAT);
colorTexture.genTexture(gl);
colorTexture.setTexParameteri(gl,GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR);
colorTexture.setTexParameteri(gl, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR);
colorTexture.setTexParameteri(gl, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP_TO_BORDER);
colorTexture.setTexParameteri(gl, GL2.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP_TO_BORDER);
}
@Override
public void updateData(GL4 gl, TransferFunction1D transferFunction,
float sampleStep) {
FloatBuffer buffer = sample(transferFunction, sampleStep);
int dim[] = new int[]{(int)Math.round(Math.sqrt(buffer.capacity()/4)),(int)Math.round(Math.sqrt(buffer.capacity()/4))};
colorTexture.update(gl, 0, buffer,dim );
}
@Override
public FloatBuffer sample(TransferFunction1D transferFunction, float stepSize) {
public FloatBuffer sample( TransferFunction1D transferFunction, float stepSize) {
//http://www.uni-koblenz.de/~cg/Studienarbeiten/SA_MariusErdt.pdf
int sampleStep=1;
TreeMap<Integer, Color> colorMap = transferFunction.getTexturColor();
//get Buffer last key is the highest number
FloatBuffer buffer = Buffers.newDirectFloatBuffer(((colorMap.lastKey()-colorMap.firstKey())+1)*4);
//make samples
Integer intervalBegin = colorMap.firstKey();
float[] integral = {0,0,0,0};
buffer.put(integral.clone());
ArrayList <float[]> integalsOfS = new ArrayList<float[]>();
ArrayList <float[]> colors = new ArrayList<float[]>();
//iterate candidates
for(Integer intervalEnd: colorMap.keySet()){
if(intervalEnd == intervalBegin){
......@@ -78,27 +104,84 @@ public class PreIntegrationSampler implements ITransferFunctionSampler {
float[] formerSampleColor = intervalBeginColor.clone();
//sample linear
for(float step = intervalBegin; step < intervalEnd; step+=sampleStep ){
for(int step = intervalBegin; step < intervalEnd; step++ ){
colors.add(sampleColor);
//increment color
for(int i =0; i< sampleColor.length; i++){
sampleColor[i]+= intervalColorGradient[i]*sampleStep;
sampleColor[i]+= intervalColorGradient[i];
}
//absorbation integral
integral[3] += calcAbsorbationIntegral(formerSampleColor[3], sampleColor[3], stepSize);
integral[3] += calcAbsorbationIntegral(formerSampleColor[3], sampleColor[3], 1);
//color integral
for(int i = 0; i< 3; i++){
integral[i] +=calcColorChannelIntegral(formerSampleColor[i], sampleColor[i],
formerSampleColor[3], sampleColor[3], stepSize);
formerSampleColor[3], sampleColor[3], 1);
}
buffer.put(integral.clone());
integalsOfS.add(integral.clone());
formerSampleColor = sampleColor.clone();
}
intervalBegin = intervalEnd;
}
//get Buffer last key is the highest number
FloatBuffer buffer = Buffers.newDirectFloatBuffer((int)Math.pow(integalsOfS.size(), 2)*4);
//classification
for(int sb = 0; sb < integalsOfS.size(); sb++){
for(int sf = 0; sf < integalsOfS.size(); sf++){
float rgba[] = {0,0,0,0};
if(sf!=sb){
float integralFront[] = integalsOfS.get(sf);
float integralBack[] = integalsOfS.get(sb);
for(int i =0; i< rgba.length; i++){
rgba[i] = stepSize/(float)(sb - sf) * (integralBack[i] - integralFront[i]);
}
}else{
//rgba = colors.get(sf).clone();
for(int i =0; i< rgba.length; i++){
rgba[i] *=stepSize;
}
}
rgba[3] = (float) (1.f - Math.exp(-rgba[3]));
buffer.put(rgba.clone());
}
}
buffer.rewind();
return buffer;
}
/*" if(vbegin - vend < minValue){",
" if(vbegin - minValueHalf < 0.0){",
" vend+= minValue*10.0;",
" }else{",
" if(vend +minValueHalf > 1.0){",
" vbegin-=minValue*10.0;",
" }else{",
" vend+=minValueHalf*10.0;",
" vbegin-=minValueHalf*10.0;",
" }",
" }",
" }",
" vec4 iFront = texture("+suvColorTexture+",vbegin*texnorm + texoffset);",
" vec4 iBack = texture("+suvColorTexture+",vend*texnorm + texoffset);",
" vec4 color = vec4(0.0);",
" vec4 iDiff = distance/(vend - vbegin) * (iBack - iFront);",
"",
" //alpha desample",
" color.a = 1.0 - exp(-iDiff.a);",
"",
" //rgb desample",
" color.rgb = iDiff.rgb;",
" return color;",
"}",*/
@Override
public void dispose(GL4 gl) {
colorTexture.delete(gl);
}
}
......@@ -5,7 +5,10 @@ import java.nio.FloatBuffer;
import java.util.TreeMap;
import com.jogamp.common.nio.Buffers;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GL4;
import bdv.jogl.VolumeRenderer.Scene.Texture;
import bdv.jogl.VolumeRenderer.ShaderPrograms.ShaderSources.functions.IFunction;
import bdv.jogl.VolumeRenderer.ShaderPrograms.ShaderSources.functions.transferfunctioninterpreter.RegularTransferFunctionInterpreter;
import bdv.jogl.VolumeRenderer.TransferFunctions.TransferFunction1D;
......@@ -17,7 +20,24 @@ import static bdv.jogl.VolumeRenderer.utils.WindowUtils.getNormalizedColor;
*/
public class RegularSampler implements ITransferFunctionSampler {
private final RegularTransferFunctionInterpreter desampler = new RegularTransferFunctionInterpreter();
private final RegularTransferFunctionInterpreter desampler = new RegularTransferFunctionInterpreter();
private Texture colorTexture;
@Override
public void init(GL4 gl, int colorTextureId) {
colorTexture = new Texture(GL2.GL_TEXTURE_1D,colorTextureId,GL2.GL_RGBA,GL2.GL_RGBA,GL2.GL_FLOAT);
colorTexture.genTexture(gl);
colorTexture.setTexParameteri(gl,GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR);
colorTexture.setTexParameteri(gl, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR);
colorTexture.setTexParameteri(gl, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP_TO_BORDER);
}
@Override
public void updateData(GL4 gl, TransferFunction1D transferFunction,
float sampleStep) {
FloatBuffer buffer = sample( transferFunction, sampleStep);
colorTexture.update(gl, 0, buffer, new int[]{buffer.capacity()/4});
}
/**
* Samples tf data and returns 1d texture
......@@ -25,6 +45,7 @@ public class RegularSampler implements ITransferFunctionSampler {
* @param sampleStep
* @return
*/
public FloatBuffer sample(TransferFunction1D transferFunction, float sampleStep){
TreeMap<Integer, Color> colorMap = transferFunction.getTexturColor();
//get Buffer last key is the highest number
......@@ -67,6 +88,7 @@ public class RegularSampler implements ITransferFunctionSampler {
buffer.rewind();
return buffer;
};
/**
......@@ -76,5 +98,10 @@ public class RegularSampler implements ITransferFunctionSampler {
public IFunction getShaderCode(){
return desampler;
}
@Override
public void dispose(GL4 gl) {
colorTexture.delete(gl);
}
}
......@@ -341,7 +341,7 @@ public class GLWindow extends JFrame {
//sample size
setSize(640,580);
setSize(600,600);
getContentPane().add(glCanvas);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment