Commit e3c727f7 authored by Kirill Terekhov's avatar Kirill Terekhov

Restructure OldDrawGrid example

Separating routines and classes in Examples/OldDrawGrid into files for future reuse. Making streamline calculator universal with respect to definition of data on various element types and adding option to visualize data as streamlines.
parent 61de3bb7
......@@ -3,12 +3,33 @@ set(SOURCE main.cpp
rotate.cpp
clipboard.cpp
rotate.h
my_glut.h
inc_glut.h
clipboard.h
color.h
coord.h
coord.cpp
octree.h)
octree.h
streamline.h
streamline.cpp
svg_line.h
svg_line.cpp
face2gl.h
face2gl.cpp
color_bar.h
color_bar.cpp
printtext.cpp
tga.h
tga.cpp
screenshot.h
screenshot.cpp
volumetric.h
volumetric.cpp
input.h
input.cpp
picker.h
picker.cpp
clipper.h
clipper.cpp)
find_package(OpenGL)
find_package(GLUT)
......
This diff is collapsed.
#ifndef _CLIPPER_H
#define _CLIPPER_H
#include "inmost.h"
#include "face2gl.h"
namespace INMOST
{
class kdtree
{
public:
struct entry
{
HandleType e;
float xyz[3];
entry(){}
entry(const entry & other);
entry & operator =(const entry & other);
} *set;
private:
int marked;
Mesh * m;
INMOST_DATA_ENUM_TYPE size;
float bbox[6];
kdtree * children;
void radix_sort(int dim, struct entry * temp);
void kdtree_build(int dim, int & done, int total, struct entry * temp);
kdtree();
inline int plane_bbox(double p[3], double n[3]) const;
bool sub_intersect_plane_edge(Tag clip_point, Tag clip_state, ElementArray<Cell> & cells, MarkerType mrk, double p[3], double n[3]);
void sub_intersect_plane_faces(Tag clip_state, double p[3], double n[3]);
void unmark_old_edges(Tag clip_state);
void clear_children();
public:
kdtree(Mesh * m);
kdtree(Mesh * m, HandleType * eset, INMOST_DATA_ENUM_TYPE size);
void intersect_plane_edge(Tag clip_point, Tag clip_state, ElementArray<Cell> & cells, MarkerType mark_cells, double p[3], double n[3]);
void intersect_plane_face(Tag clip_state, double p[3], double n[3]);
~kdtree();
};
class clipper
{
public:
struct edge_point
{
double val;
Storage::real xyz[3];
Storage::integer edge;
edge_point();
edge_point(Storage::real _xyz[3], Storage::integer n, float v);
bool operator ==(const edge_point& b) const;
bool operator !=(const edge_point& b) const;
void print();
};
private:
Tag clip_point, clip_state;
kdtree * tree;
Tag clips, clipsv, clipsn;
MarkerType marker;
ElementArray<Cell> cells;
Mesh * mm;
public:
~clipper();
clipper(Mesh * m);
double compute_value(Edge e, Storage::real * pnt);
void clip_plane(Storage::real p[3], Storage::real n[3]);
void gen_clip(std::vector<face2gl> & out, Storage::real n[3],bool elevation);
void draw_clip(INMOST_DATA_ENUM_TYPE pace, Storage::real n[3], bool elevation);
void draw_clip_edges(INMOST_DATA_ENUM_TYPE pace, Storage::real n[3], bool elevation);
INMOST_DATA_ENUM_TYPE size();
};
class bnd_clipper
{
Tag clip_state;
kdtree * tree; Mesh * mm;
HandleType * faces;
INMOST_DATA_ENUM_TYPE nfaces;
public:
~bnd_clipper();
bnd_clipper(Mesh * m, HandleType * _faces, INMOST_DATA_ENUM_TYPE size);
double compute_value(Node n1, Node n2, Storage::real * c1, Storage::real * c2, Storage::real * pnt);
void clip_plane(Storage::real p[3], Storage::real n[3]);
void gen_clip(std::vector<face2gl> & out, Storage::real p[3], Storage::real n[3], bool elevation);
void draw_clip(INMOST_DATA_ENUM_TYPE pace, Storage::real p[3], Storage::real n[3]);
void draw_clip_edges(INMOST_DATA_ENUM_TYPE pace);
INMOST_DATA_ENUM_TYPE size();
};
}
#endif
\ No newline at end of file
#ifndef _COLOR_H
#define _COLOR_H
#include "my_glut.h"
#include "inc_glut.h"
#include <iostream>
#include <sstream>
struct color_t
{
......
#include "color_bar.h"
#include "inc_glut.h"
#include "svg_line.h"
#include <algorithm>
namespace INMOST
{
color_bar * color_bar::CommonColorBar = NULL;
Tag color_bar::vtag = Tag();
ElementType color_bar::vtype = NONE;
bool color_bar::smooth = false;
ElementType GetVisualizationType()
{
return color_bar::GetVisualizationType();
}
bool isVisualizationSmooth()
{
return color_bar::isVisualizationSmooth();
}
void color_bar::InitColorBar()
{
if (CommonColorBar)
delete CommonColorBar;
CommonColorBar = new color_bar;
}
void color_bar::DestroyColorBar()
{
delete CommonColorBar;
}
color_bar * color_bar::GetColorBar()
{
return CommonColorBar;
}
color_bar::~color_bar()
{
if (glIsTexture(texture))
glDeleteTextures(1, &texture);
}
color_bar::color_bar()
{
min = 0;
max = 1;
comment = "";
/*
ticks.push_back(0.f);
ticks.push_back(0.2f);
ticks.push_back(0.4f);
ticks.push_back(0.6f);
ticks.push_back(0.8f);
ticks.push_back(1.f);
//colors.push_back(color_t(1,0,0));
//colors.push_back(color_t(1,1,0));
//colors.push_back(color_t(0,1,0));
//colors.push_back(color_t(0,1,1));
//colors.push_back(color_t(0,0,1));
//colors.push_back(color_t(1,0,1));
colors.push_back(color_t(1,0,1));
colors.push_back(color_t(0,0,1));
colors.push_back(color_t(0,1,1));
colors.push_back(color_t(0,1,0));
colors.push_back(color_t(1,1,0));
colors.push_back(color_t(1,0,0));
*/
//inversed gnuplot color scheme
ticks.push_back(0.f);
ticks.push_back(0.05f);
ticks.push_back(0.5f);
ticks.push_back(0.75f);
ticks.push_back(0.95f);
ticks.push_back(1.f);
colors.push_back(color_t(1, 1, 1));
colors.push_back(color_t(1, 1, 0));
colors.push_back(color_t(0.85, 0, 0));
colors.push_back(color_t(0.65, 0.25, 0.85));
colors.push_back(color_t(0.45, 0, 0.55));
colors.push_back(color_t(0, 0, 0));
samples = 4096;
float * pixel_array = new float[(samples + 2) * 4];
for (int q = 0; q < samples + 2; ++q)
{
float t = 1.0f*q / static_cast<float>(samples + 1);
color_t c = pick_color(t);
//countour lines
//if( ((q+1) % 128 == 0 || (q+1) % 128 == 127) && (q+1) < samples )
// c = pick_color(1-t) + color_t(0,2*t*(1-t),0);
pixel_array[(q)* 4 + 0] = c.r();
pixel_array[(q)* 4 + 1] = c.g();
pixel_array[(q)* 4 + 2] = c.b();
pixel_array[(q)* 4 + 3] = c.a();
}
pixel_array[0] = 0;
pixel_array[1] = 1;
pixel_array[2] = 0;
pixel_array[3] = 1;
pixel_array[(samples + 1) * 4 + 0] = 0;
pixel_array[(samples + 1) * 4 + 1] = 1;
pixel_array[(samples + 1) * 4 + 2] = 0;
pixel_array[(samples + 1) * 4 + 3] = 1;
glEnable(GL_TEXTURE);
glEnable(GL_TEXTURE_1D);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_1D, texture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage1D(GL_TEXTURE_1D, 0, 4, samples + 2, 1, GL_RGBA, GL_FLOAT, pixel_array);
std::cout << "Created texture " << texture << std::endl;
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
UnbindTexture();
delete[] pixel_array;
//colors.push_back(color_t(1,0,0));
}
color_t color_bar::pick_color(float value) const
{
if (value < min)
return color_t(0.4, 1.0, 0.4);
if (value > max)
return color_t(0, 0.6, 0);
float t = (value - min) / (max - min);
std::vector<float>::const_iterator it = std::lower_bound(ticks.begin(), ticks.end(), t);
size_t pos = it - ticks.begin();
if (it == ticks.end() || pos >= ticks.size())
{
return colors.back();
}
if (pos == 0)
{
return colors[0];
}
float interp = (t - ticks[pos - 1]) / (ticks[pos] - ticks[pos - 1]);
return (colors[pos] * interp + colors[pos - 1] * (1 - interp));
}
void color_bar::BindTexture()
{
//glDisable( GL_TEXTURE_GEN_S );
glDisable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_1D);
glBindTexture(GL_TEXTURE_1D, texture);
}
void color_bar::UnbindTexture()
{
glDisable(GL_TEXTURE_1D);
}
double color_bar::pick_texture(double value) const
{
double eps = 1.0 / static_cast<double>(samples);
return (value - min) / (max - min)*(1 - 2 * eps) + eps;
//return std::max(std::min((value-min)/(max-min),0.99),0.01);
}
void color_bar::Draw()
{
float text_pos = -0.89;
float left = -0.95;
float right = -0.9;
float bottom = -0.75;
float top = 0.75;
BindTexture();
glBegin(GL_QUADS);
glTexCoord1d(1.0 / 1024.0);
glVertex2f(left, bottom);
glVertex2f(right, bottom);
glTexCoord1d(1.0);
glVertex2f(right, top);
glVertex2f(left, top);
/*
for(int i = 0; i < ticks.size()-1; ++i)
{
colors[i].set_color();
glVertex2f(left,bottom+ticks[i]*(top-bottom));
glVertex2f(right,bottom+ticks[i]*(top-bottom));
colors[i+1].set_color();
glVertex2f(right,bottom+ticks[(i+1)]*(top-bottom));
glVertex2f(left,bottom+ticks[(i+1)]*(top-bottom));
}
*/
glEnd();
UnbindTexture();
int tickmarks = 11;
glColor4f(0, 0, 0, 1);
for (int i = 0; i < tickmarks; ++i)
{
float t = 1.0f*i / static_cast<float>(tickmarks - 1);
glRasterPos2f(text_pos, bottom + t*(top - bottom));
printtext("%g", min + t*(max - min));
}
if (comment != "")
{
glRasterPos2f(left, bottom - 0.04);
printtext("%s", comment.c_str());
}
glBegin(GL_LINE_LOOP);
glVertex2f(left, bottom);
glVertex2f(right, bottom);
glVertex2f(right, top);
glVertex2f(left, top);
glEnd();
glBegin(GL_LINES);
for (int i = 0; i < tickmarks; ++i)
{
float t = 1.0f*i / static_cast<float>(tickmarks - 1);
float pos = bottom + t*(top - bottom);
glVertex2f(left, pos);
glVertex2f(left + (right - left)*0.2, pos);
glVertex2f(right + (left - right)*0.25, pos);
glVertex2f(right, pos);
}
glEnd();
}
void color_bar::DrawSVG(std::ostream & file, double modelview[16], double projection[16], int viewport[4])
{
float text_pos = -0.89;
float left = -0.95;
float right = -0.9;
float bottom = -0.75;
float top = 0.75;
double px, py;
double px1, py1, z;
double px2, py2;
int height = glutGet(GLUT_WINDOW_HEIGHT);
file << "<g>" << std::endl;
for (int i = 0; i < ticks.size() - 1; ++i)
{
colors[i].set_color();
gluProject(left, bottom + ticks[i] * (top - bottom), 0, modelview, projection, viewport, &px1, &py1, &z); py1 = height - py1;
gluProject(right, bottom + ticks[i + 1] * (top - bottom), 0, modelview, projection, viewport, &px2, &py2, &z); py2 = height - py2;
file << "<def>" << std::endl;
file << "<linearGradient id=\"grad" << i << "\" gradientUnits=\"userSpaceOnUse\" x1=\"" << px1 << "\" y1=\"" << py1 << "\" x2=\"" << px1 << "\" y2=\"" << py2 << "\">" << std::endl;
file << "<stop offset=\"0%\" stop-color=\"" << colors[i].svg_rgb() << "\"/>" << std::endl;
file << "<stop offset=\"100%\" stop-color=\"" << colors[i + 1].svg_rgb() << "\"/>" << std::endl;
file << "</linearGradient>" << std::endl;
file << "</def>" << std::endl;
file << "<rect stroke=\"none\" x=\"" << px1 << "\" y=\"" << py2 << "\" width=\"" << px2 - px1 << "\" height=\"" << py1 - py2 << "\" fill=\"url(#grad" << i << ")\"/>" << std::endl;
}
int tickmarks = 11;
for (int i = 0; i < tickmarks; ++i)
{
float t = 1.0f*i / static_cast<float>(tickmarks - 1);
gluProject(text_pos, bottom + t*(top - bottom), 0, modelview, projection, viewport, &px, &py, &z); py = height - py;
file << "<text x=\"" << px << "\" y=\"" << py << "\">" << min + t*(max - min) << "</text>" << std::endl;
}
if (comment != "")
{
gluProject(left, bottom - 0.04, 0, modelview, projection, viewport, &px, &py, &z); py = height - py;
file << "<text x=\"" << px << "\" y=\"" << py << "\">" << comment.c_str() << "</text>" << std::endl;
}
gluProject(left, bottom, 0, modelview, projection, viewport, &px1, &py1, &z); py1 = height - py1;
gluProject(right, top, 0, modelview, projection, viewport, &px2, &py2, &z); py2 = height - py2;
file << "<rect stroke=\"black\" fill=\"none\" x=\"" << px1 << "\" y=\"" << py2 << "\" width=\"" << px2 - px1 << "\" height=\"" << py1 - py2 << "\"/>" << std::endl;
file << "<g stroke=\"black\">" << std::endl;
for (int i = 0; i < tickmarks; ++i)
{
float t = 1.0f*i / static_cast<float>(tickmarks - 1);
float pos = bottom + t*(top - bottom);
svg_line(file, left, pos, 0, left + (right - left)*0.2, pos, 0, modelview, projection, viewport);
svg_line(file, right + (left - right)*0.25, pos, 0, right, pos, 0, modelview, projection, viewport);
}
file << "</g>" << std::endl;
file << "</g>" << std::endl;
}
color_bar * GetColorBar() { return color_bar::GetColorBar(); }
bool isColorBarEnabled() { return color_bar::isColorBarEnabled(); }
Tag GetVisualizationTag() { return color_bar::GetVisualizationTag(); }
}
\ No newline at end of file
#ifndef _COLOR_BAR_H
#define _COLOR_BAR_H
#include "inmost.h"
#include "color.h"
#include <vector>
namespace INMOST
{
class color_bar
{
static color_bar * CommonColorBar;
static Tag vtag;
static ElementType vtype;
static bool smooth;
float min, max;
std::vector<float> ticks; //ticks from 0 to 1 for each color
std::vector<color_t> colors; //4 floats for each tick
std::string comment;
unsigned texture;
int samples;
public:
color_bar();
~color_bar();
void set_comment(std::string text) { comment = text; }
void set_min(float newmin) { min = newmin; }
void set_max(float newmax) { max = newmax; }
float get_min() { return min; }
float get_max() { return max; }
color_t pick_color(float value) const;
void BindTexture();
void UnbindTexture();
double pick_texture(double value) const;
void Draw();
void DrawSVG(std::ostream & file, double modelview[16], double projection[16], int viewport[4]);
static void InitColorBar();
static void DestroyColorBar();
static color_bar * GetColorBar();
static bool isColorBarEnabled() { return vtag.isValid(); }
static Tag GetVisualizationTag() { return vtag; }
static ElementType GetVisualizationType() { return vtype; }
static bool isVisualizationSmooth() { return smooth; }
static void SetVisualizationTag(Tag t, ElementType et, bool st) { vtag = t; vtype = et; smooth = st; }
static void UnsetVisualizationTag() { vtag = Tag(); vtype = NONE;}
};
Tag GetVisualizationTag();
ElementType GetVisualizationType();
bool isVisualizationSmooth();
color_bar * GetColorBar();
bool isColorBarEnabled();
}
#endif
\ No newline at end of file
This diff is collapsed.
#ifndef _FACE2GL_H
#define _FACE2GL_H
#include "inmost.h"
#include "inc_glut.h"
#include "color.h"
namespace INMOST
{
class face2gl
{
float dist;
double c[4];
double cnt[3];
bool flag;
ElementType etype;
Storage::integer id;
std::vector<double> verts;
std::vector<double> texcoords;
std::vector<color_t> colors;
color_t cntcolor;
double cnttexcoord;
public:
void shift(double x, double y, double z);
static void radix_sort_dist(std::vector<face2gl> & set);
face2gl();
face2gl(const face2gl & other);
face2gl & operator =(face2gl const & other);
~face2gl();
void draw_colour() const;
void svg_draw_colour(std::ostream & file, bool drawedges, double modelview[16], double projection[16], int viewport[4]) const;
void draw_colour_alpha(double alpha) const;
void draw() const;
void svg_draw(std::ostream & file, bool drawedges, double modelview[16], double projection[16], int viewport[4]) const;
void drawedges() const;
void svg_drawedges(std::ostream & file, double modelview[16], double projection[16], int viewport[4]) const;
bool operator <(const face2gl & other) const { return dist < other.dist; }
void set_color(double r, double g, double b, double a) { c[0] = r; c[1] = g; c[2] = b; c[3] = a; }
void add_vert(double x, double y, double z) { unsigned s = (unsigned)verts.size(); verts.resize(s + 3); verts[s] = x; verts[s + 1] = y; verts[s + 2] = z; }
void add_vert(double v[3]) { verts.insert(verts.end(), v, v + 3); }
void add_color(color_t c) { colors.push_back(c); }
void add_texcoord(double val) { texcoords.push_back(val); }
double * get_vert(int k) { return &verts[k * 3]; }
unsigned size() { return (unsigned)verts.size() / 3; }
void set_center(double _cnt[3], color_t c = color_t(0, 0, 0, 0)) {cnt[0] = _cnt[0]; cnt[1] = _cnt[1]; cnt[2] = _cnt[2]; cntcolor = c;}
void get_center(float _cnt[3]) {_cnt[0] = cnt[0]; _cnt[1] = cnt[1]; _cnt[2] = cnt[2];}
void get_center(double _cnt[3]) {_cnt[0] = cnt[0]; _cnt[1] = cnt[1]; _cnt[2] = cnt[2];}
double * get_center() { return cnt; }
void compute_center();
void compute_center_color();
void compute_center_texcoord();
void compute_dist(double cam[3]) {dist = sqrt((cnt[0] - cam[0])*(cnt[0] - cam[0]) + (cnt[1] - cam[1])*(cnt[1] - cam[1]) + (cnt[2] - cam[2])*(cnt[2] - cam[2]));}
void set_flag(bool set) { flag = set; }
bool get_flag() { return flag; }
void set_elem(ElementType _etype, Storage::integer _id) { etype = _etype; id = _id; }
Element get_elem(Mesh * m) { return m->ElementByLocalID(etype, id); }
};
face2gl DrawFace(Element f);
void svg_draw_faces_nc(std::ostream & file, std::vector<face2gl> & set, bool drawedges, double modelview[16], double projection[16], int viewport[4], int highlight = -1);
void svg_draw_faces(std::ostream & file, std::vector<face2gl> & set, bool drawedges, double modelview[16], double projection[16], int viewport[4], int highlight = -1);
void svg_draw_edges(std::ostream & file, std::vector<face2gl> & set, double modelview[16], double projection[16], int viewport[4], int highlight = -1);
void draw_faces_nc(std::vector<face2gl> & set, int highlight = -1);
void draw_faces(std::vector<face2gl> & set, int highlight = -1);
void draw_faces_alpha(std::vector<face2gl> & set, double alpha);
void draw_edges(std::vector<face2gl> & set, int highlight = -1);
void draw_faces_interactive_nc(std::vector<face2gl> & set);
void draw_faces_interactive(std::vector<face2gl> & set);
void draw_faces_interactive_alpha(std::vector<face2gl> & set, double alpha);
void draw_edges_interactive(std::vector<face2gl> & set);
}
#endif
\ No newline at end of file
#version 400
in vec3 EntryPoint;
in vec4 ExitPointCoord;
uniform sampler2D ExitPoints;
uniform sampler3D VolumeTex;
uniform sampler1D TransferFunc;
uniform float StepSize;
uniform vec2 ScreenSize;
layout (location = 0) out vec4 FragColor;
void main()
{
// ExitPointCoord
vec3 exitPoint = texture(ExitPoints, gl_FragCoord.st/ScreenSize).xyz;
// that will actually give you clip-space coordinates rather than
// normalised device coordinates, since you're not performing the perspective
// division which happens during the rasterisation process (between the vertex
// shader and fragment shader
// vec2 exitFragCoord = (ExitPointCoord.xy / ExitPointCoord.w + 1.0)/2.0;
// vec3 exitPoint = texture(ExitPoints, exitFragCoord).xyz;
if (EntryPoint == exitPoint)
//background need no raycasting
discard;
vec3 dir = exitPoint - EntryPoint;
float len = length(dir); // the length from front to back is calculated and used to terminate the ray
vec3 deltaDir = normalize(dir) * StepSize;
float deltaDirLen = length(deltaDir);
vec3 voxelCoord = EntryPoint;
vec4 colorAcum = vec4(0.0); // The dest color
float alphaAcum = 0.0; // The dest alpha for blending
float intensity;
float lengthAcum = 0.0;
vec4 colorSample; // The src color
float alphaSample; // The src alpha
// backgroundColor
vec4 bgColor = vec4(1.0, 1.0, 1.0, 0.0);
for(int i = 0; i < 1600; i++)
{
// scaler value
intensity = texture(VolumeTex, voxelCoord).x;
colorSample = texture(TransferFunc, intensity);
// modulate the value of colorSample.a
// front-to-back integration
if (colorSample.a > 0.0) {
// accomodate for variable sampling rates (base interval defined by mod_compositing.frag)
colorSample.a = 1.0 - pow(1.0 - colorSample.a, StepSize*200.0f);
colorAcum.rgb += (1.0 - colorAcum.a) * colorSample.rgb * colorSample.a;
colorAcum.a += (1.0 - colorAcum.a) * colorSample.a;
}
voxelCoord += deltaDir;
lengthAcum += deltaDirLen;
if (lengthAcum >= len )
{
colorAcum.rgb = colorAcum.rgb*colorAcum.a + (1 - colorAcum.a)*bgColor.rgb;
break; // terminate if opacity > 1 or the ray is outside the volume
}
else if (colorAcum.a > 1.0)
{
colorAcum.a = 1.0;
break;
}
}
FragColor = colorAcum;
// for test
// FragColor = vec4(EntryPoint, 1.0);
// FragColor = vec4(exitPoint, 1.0);
}
#ifndef _INC_GLUT_H
#define _INC_GLUT_H
#if defined (__APPLE__) || defined(MAXOSX)
#include <GLUT/glut.h>
#endif
......@@ -16,3 +19,7 @@
#if defined(__linux__)
#include <GL/glut.h>
#endif
void printtext(const char * fmt, ...); //in printtext.cpp
#endif
\ No newline at end of file