00001 #include "VTransferFunction.h"
00002 #include "VTransferFunctionNode.h"
00003 #include "V2Ddraw.h"
00004 #include <vector>
00005 #include <algorithm>
00006 #include <iostream>
00007 #include "vmath.h"
00008 #include <math.h>
00009
00010 using namespace std;
00011
00012 VTransferFunction::VTransferFunction(int x, int y,int width, int height,float* alpha)
00013 {
00014 this->x = x;
00015 this->y = y;
00016 this->width = width;
00017 this->height = height;
00018 this->alpha = alpha;
00019 this->dragging = false;
00020 this->chooser = new VColorChooser(alpha,x,y,width,height);
00021 this->currentnode = 0;
00022 this->tex = 0;
00023 VTransferFunctionNode * begin = new VTransferFunctionNode(this->x,this->y+this->height);
00024 float * color = begin->getColor();
00025 color[0] = color[1] = color[2] = 0.0f;
00026 begin->setChoosed(false);
00027 this->nodes.push_back(begin);
00028 VTransferFunctionNode * end = new VTransferFunctionNode(this->x+this->width,this->y);
00029 color = end->getColor();
00030 color[0] = color[1] = color[2] = 1.0f;
00031 end->setChoosed(false);
00032 this->nodes.push_back(end);
00033 this->length = 4096;
00034 colors = new float[4*length];
00035 }
00036
00037 void VTransferFunction::draw() {
00038
00039 V2Ddraw::drawRect(this->x,this->y,this->width,this->height);
00040
00041 stdx::sort(nodes.begin(),nodes.end());
00042 int startx = this->x;
00043 int starty = this->y+this->height;
00044 for(ptr_vector<VTransferFunctionNode>::iterator it=nodes.begin(); it!=nodes.end(); it++) {
00045 glBegin(GL_LINES);
00046 glVertex2f(startx,starty);
00047 glVertex2f((*it).getx(),(*it).gety());
00048 glEnd();
00049 startx = (*it).getx();
00050 starty = (*it).gety();
00051 (*it).draw();
00052 }
00053
00054
00055
00056
00057
00058 float * c = this->nodes.front().getColor();
00059
00060 float previous_color[3];
00061 previous_color[0] = c[0];
00062 previous_color[1] = c[1];
00063 previous_color[2] = c[2];
00064 startx = this->x;
00065 int y1 = this->y+this->height+5;
00066 int y2 = this->y+this->height+25;
00067 for(ptr_vector<VTransferFunctionNode>::iterator it=nodes.begin(); it!=nodes.end(); it++) {
00068 if(it!=nodes.begin()) {
00069 float * current_color = (*it).getColor();
00070 int xn = (*it).getx();
00071 glBegin(GL_QUADS);
00072 glColor4f(previous_color[0],previous_color[1],previous_color[2],*(this->alpha));
00073 glVertex2f(startx,y1);
00074 glColor4f(current_color[0],current_color[1],current_color[2],*(this->alpha));
00075 glVertex2f(xn,y1);
00076 glColor4f(current_color[0],current_color[1],current_color[2],*(this->alpha));
00077 glVertex2f(xn,y2);
00078 glColor4f(previous_color[0],previous_color[1],previous_color[2],*(this->alpha));
00079 glVertex2f(startx,y2);
00080 glEnd();
00081 startx = xn;
00082 previous_color[0] = current_color[0];
00083 previous_color[1] = current_color[1];
00084 previous_color[2] = current_color[2];
00085 }
00086 }
00087
00088 if(this->chooser->isActive()) {
00089 this->chooser->draw();
00090 }
00091 }
00092
00093 void VTransferFunction::pressed(int x, int y) {
00094
00095 for(ptr_vector<VTransferFunctionNode>::iterator it=nodes.begin(); it!=nodes.end(); it++) {
00096 if((*it).isInside(x,y)) {
00097 this->currentnode = &(*it);
00098 }
00099 }
00100 }
00101
00102 void VTransferFunction::released(int x,int y) {
00103 if(!this->currentnode && !this->dragging && !this->chooser->isActive()) {
00104 this->chooser->setActive(true,x,y);
00105 this->nodes.push_back(new VTransferFunctionNode(x,y));
00106 }
00107 else if(this->currentnode && !this->dragging && !this->chooser->isActive()) {
00108 this->chooser->setActive(true,x,y);
00109 currentnode->setChoosed(true);
00110 }
00111 else if(!this->currentnode && !this->dragging && this->chooser->isActive()) {
00112 if(this->chooser->isInside(x,y)) {
00113 for(ptr_vector<VTransferFunctionNode>::iterator it=nodes.begin(); it!=nodes.end(); it++) {
00114 if((*it).isChoosed()) {
00115 float * color = new float[3];
00116 this->chooser->getColor(x,y,color);
00117 float * color_node = (*it).getColor();
00118 color_node[0] = color[0];
00119 color_node[1] = color[1];
00120 color_node[2] = color[2];
00121
00122 delete color;
00123 this->chooser->setActive(false,0,0);
00124 (*it).setChoosed(false);
00125 }
00126 }
00127 }
00128 this->renderTexture();
00129 } else if(this->dragging) {
00130 this->renderTexture();
00131 }
00132
00133 this->currentnode = 0;
00134 this->dragging = false;
00135 }
00136
00137 void VTransferFunction::drag(int x, int y) {
00138 this->dragging = true;
00139 stdx::sort(nodes.begin(),nodes.end());
00140 bool endknoten = (this->currentnode == &this->nodes.front()) || (this->currentnode == &this->nodes.back());
00141 if(currentnode && !endknoten) {
00142 currentnode->setx(x);
00143 currentnode->sety(y);
00144 } else if(currentnode && endknoten) {
00145 currentnode->sety(y);
00146 }
00147 this->renderTexture();
00148 }
00149
00150 bool VTransferFunction::isInside(int xm, int ym) {
00151 return xm > this->x && xm < this->x + this->width && ym > this->y && ym < this->y + this->height;
00152 }
00153
00154 GLuint * VTransferFunction::getTexture() {
00155 return &this->tex;
00156 }
00157
00158 void VTransferFunction::renderTexture() {
00159 stdx::sort(this->nodes.begin(),this->nodes.end());
00160
00161 float * c = this->nodes.front().getColor();
00162 Vector4<float> color(c[0],c[1],c[2],this->nodes.front().getOpacity(this->height));
00163 int anfang = 0;
00164 int posx = this->x;
00165 for(ptr_vector<VTransferFunctionNode>::iterator it=nodes.begin(); it!=nodes.end(); it++) {
00166 if(it!=nodes.begin()) {
00167 float * c = (*it).getColor();
00168 float op = (*it).getOpacity(this->height);
00169 Vector4<float> color2(c[0],c[1],c[2],op);
00170 double intervall_norm = (double)((*it).getx() - posx)/(double)this->width;
00171 int intervall = (int)floor((float)(intervall_norm*(float)length)+0.5);
00172 float f = 0.0f;
00173 for(int i = anfang; i < anfang+intervall; i++) {
00174 Vector4<float> interpol = color.lerp(f,color2);
00175 colors[4*i+0] = interpol[0];
00176 colors[4*i+1] = interpol[1];
00177 colors[4*i+2] = interpol[2];
00178 colors[4*i+3] = interpol[3];
00179 f += 1.0f/(float)intervall;
00180
00181 }
00182 anfang += intervall;
00183 posx = (*it).getx();
00184 color = color2;
00185 }
00186 }
00187 c = this->nodes.back().getColor();
00188 Vector4<float> ende(c[0],c[1],c[2],this->nodes.back().getOpacity(this->height));
00189 for(int i = anfang; i< length; i++) {
00190 colors[4*i+0] = ende[0];
00191 colors[4*i+1] = ende[1];
00192 colors[4*i+2] = ende[2];
00193 colors[4*i+3] = ende[3];
00194
00195 }
00196
00197
00198 if(glIsTexture(this->tex)) {
00199 glDeleteTextures(1,&this->tex);
00200 }
00201 glGenTextures(1,&this->tex);
00202 glBindTexture(GL_TEXTURE_1D, this->tex);
00203 glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 4*length, 0, GL_RGBA, GL_FLOAT, colors);
00204 }
00205
00206 VTransferFunction::~VTransferFunction(void)
00207 {
00208 delete this->chooser;
00209 delete[] this->colors;
00210 }