Subversion Repositories gelsvn

Rev

Rev 630 | Rev 647 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
572 jab 1
/* ----------------------------------------------------------------------- *
2
 * This file is part of GEL, http://www.imm.dtu.dk/GEL
3
 * Copyright (C) the authors and DTU Informatics
4
 * For license and list of authors, see ../../doc/intro.pdf
5
 * ----------------------------------------------------------------------- */
578 jab 6
/**
7
 * @file ManifoldRenderer.h
8
 * @brief Tool for rendering a HMesh Manifold.
9
 */
572 jab 10
 
557 jab 11
#ifndef __MESHEDIT_RENDERER_H__
12
#define __MESHEDIT_RENDERER_H__
13
 
631 janba 14
#include "../CGLA/Vec2d.h"
601 jab 15
#include "../GL/glew.h"
16
#include "../GLGraphics/draw.h"
17
#include "../GLGraphics/IDBufferWireFrameRenderer.h"
18
#include "../CGLA/Vec4d.h"
557 jab 19
 
20
namespace HMesh
21
{
22
    template<typename ITEM>
23
    class VertexAttributeVector;
24
}
25
 
26
namespace GLGraphics {
27
 
28
/** Ancestral class for Manifold rendering. Do not use directly. Its only purpose is to
29
	create a display list and remove it when the object is destroyed. This is an example
30
	of the RAII "resource acquisition is initialization" idiom */
31
class ManifoldRenderer
32
	{
33
	protected:
34
		GLuint display_list;
35
	public:
36
		ManifoldRenderer(): display_list(glGenLists(1))	{}
37
		virtual ~ManifoldRenderer()
38
		{
39
			glDeleteLists(display_list, 1);
40
		}
41
		virtual void draw()
42
		{
43
			glCallList(display_list);
44
		}
45
	};
46
 
47
 
48
/** Wireframe rendering. This is a nasty complex class that relies on other classes. The trouble
49
	is that for non-triangle meshes, we need to use another approach than for triangle meshes.
50
	This class is really a front end for a couple of other classes. */
51
class WireframeRenderer: public ManifoldRenderer
52
	{
53
		GLGraphics::IDBufferWireframeRenderer* idbuff_renderer;
54
 
55
		int maximum_face_valency(const HMesh::Manifold& m);
56
 
57
	public:
58
		~WireframeRenderer()
59
		{
60
			delete idbuff_renderer;
61
		}
62
 
63
		WireframeRenderer(HMesh::Manifold& m, bool flat);
64
 
65
		void draw();
66
	};
67
 
68
/** SimpleShaderRenderer is a very basic class for drawing a Manifold with shading.
69
	It is a convenient way to draw a surface using vertex and fragment shaders since it takes
70
	care of initializing the shaders and producing a display list for the geometry. 
71
 
72
	Geometry shaders typically add more complexity and are left out of this class, so you cannot add a
73
	geometry shader.
74
 
75
	While this class can be used directly, the normal procedure is to inherit from SimpleShaderRenderer
76
	and then pass the shaders to the constructor. The strings defining the shaders would fit
77
	nicely as static constant strings (see e.g. ToonRenderer or GlazedRenderer) in your inherited class.
78
 
79
	If you need to define more attributes or uniforms, you need to take charge. Your inherited class's 
80
	constructor should then use the default constructor of SimpleShaderRenderer. You can call init_shaders
81
	to initialize the shaders and then compile the display list yourself with the needed uniforms and
82
	attributes - rather than calling compile_display_list which only puts vertices and normals in the list. 
83
 */
84
class SimpleShaderRenderer: public ManifoldRenderer
85
	{
86
		/// Compile the vertex and fragment shaders and link to form shader program.
87
		void init_shaders(const std::string& vss, 
88
						  const std::string& fss);
89
 
90
		/// Produce a display list containing geometry and normals (which may be smooth or per face).
91
		void compile_display_list(const HMesh::Manifold& m, bool smooth);
92
 
93
	protected:
94
 
95
		GLuint prog,vs,fs;
96
 
97
	public:
98
 
99
		/// This constructor simply calls init_shaders and then compile_display_list.
100
		SimpleShaderRenderer(const HMesh::Manifold& m, 
101
							bool smooth, 
102
							const std::string& vss, 
103
							const std::string& fss)
104
		{
105
			init_shaders(vss,fss);
106
			compile_display_list(m, smooth);
107
		}
108
 
109
		/** This constructor simply initializes the shaders. It does not create the display list.
110
			Use if you shader has extra attributes. */
111
		SimpleShaderRenderer(const std::string& vss, 
112
							 const std::string& fss) {init_shaders(vss,fss);}
113
 
114
		/// Releases the program and shaders.
115
		~SimpleShaderRenderer()
116
		{
117
			glDeleteProgram(prog);
118
			glDeleteShader(vs);
119
			glDeleteShader(fs);
120
		}
121
 
122
		/// Do the actual drawing. Simply calls the display list if this function is not overloaded.
123
		virtual void draw();
124
 
125
	};
126
 
127
/** Ugly basic gouraud rendering. This class uses OpenGL's fixed function pipeline. */
128
class NormalRenderer: public SimpleShaderRenderer
129
{
130
    const static std::string vss;
131
    const static std::string fss;
132
 
133
public:
134
    NormalRenderer(const HMesh::Manifold& m, bool smooth):
135
    SimpleShaderRenderer(m, smooth, vss, fss) {}
136
};
137
 
138
 
139
/** Render reflection lines. This class renders the object as if it is specular and inside
140
	an infinitely long, vertical cylinder with white strips (also vertical). Useful if you
141
	want to see whether the surface is smooth or has kinks. */
142
class ReflectionLineRenderer: public SimpleShaderRenderer
143
	{
144
		const static std::string vss;
145
		const static std::string fss;
146
	public:
147
		ReflectionLineRenderer(const HMesh::Manifold& m, bool smooth):
148
			SimpleShaderRenderer(m, smooth, vss, fss) {}
149
 
150
	};
151
 
152
/** Render isophotes with respect to a lightsource in the eye. Useful if you
153
 want to see whether the surface is smooth or has kinks. */
154
class IsophoteLineRenderer: public SimpleShaderRenderer
155
	{
156
		const static std::string vss;
157
		const static std::string fss;
158
	public:
159
		IsophoteLineRenderer(const HMesh::Manifold& m, bool smooth):
160
		SimpleShaderRenderer(m, smooth, vss, fss) {}
161
 
162
	};
163
 
164
/** The toon renderer simply quantizes the shading to give a toonish appearance
165
	with a fat black silhouette. */
166
 
167
class ToonRenderer: public SimpleShaderRenderer
168
	{
169
		const static std::string vss;
170
		const static std::string fss;
171
	public:
172
		ToonRenderer(const HMesh::Manifold& m, bool smooth):
173
		SimpleShaderRenderer(m, smooth, vss, fss) {}
174
 
175
	};
176
 
177
/** Render like glazed ceramics. Looks cool. I will add more to this. */
178
class GlazedRenderer: public SimpleShaderRenderer
179
	{
180
		float bsphere_rad;
181
		const static std::string vss;
182
		const static std::string fss;
183
	public:
184
		GlazedRenderer(const HMesh::Manifold& m, bool smooth, float _bsphere_rad=1.0):
185
		SimpleShaderRenderer(m, smooth, vss, fss), bsphere_rad(_bsphere_rad) {}
186
		void draw();
187
	};
188
 
189
/** Render a scalar field. Positive scalars are mapped to blue and negative to red.
190
	This class also has controls for gamma correction which is highly useful if the 
191
	scalars are mostly small or large and simply scaling to the 0-1 range does not 
192
	produce a good result. */
193
class ScalarFieldRenderer: public SimpleShaderRenderer
194
	{
195
		const static std::string vss;
196
		const static std::string fss;
197
	public:
198
		ScalarFieldRenderer(const HMesh::Manifold& m, bool smooth, HMesh::VertexAttributeVector<double>& field, double max_val, float gamma = 2.2);
199
	};
200
 
572 jab 201
    /** Render a scalar field. Positive scalars are mapped to blue and negative to red.
202
     This class also has controls for gamma correction which is highly useful if the 
203
     scalars are mostly small or large and simply scaling to the 0-1 range does not 
204
     produce a good result. */
205
    class PeriodicScalarFieldRenderer: public SimpleShaderRenderer
206
	{
207
		const static std::string vss;
208
		const static std::string fss;
209
	public:
210
		PeriodicScalarFieldRenderer(const HMesh::Manifold& m, bool smooth, HMesh::VertexAttributeVector<double>& field, float gamma = 2.2);
211
	};
212
 
631 janba 213
    /** Render a scalar field. Positive scalars are mapped to blue and negative to red.
214
     This class also has controls for gamma correction which is highly useful if the
215
     scalars are mostly small or large and simply scaling to the 0-1 range does not
216
     produce a good result. */
217
    class CircleFieldRenderer: public SimpleShaderRenderer
218
	{
219
		const static std::string vss;
220
		const static std::string fss;
221
	public:
222
		CircleFieldRenderer(const HMesh::Manifold& m, bool smooth, HMesh::VertexAttributeVector<CGLA::Vec2d>& field, float gamma = 2.2);
223
	};
224
 
225
 
557 jab 226
/** Ambient occlusion renderer. Very similar to ScalarFieldRender. Simply assumes that the input values are
227
	mean curvatures which in some sense indicate how concave the surface is.*/
228
class AmbientOcclusionRenderer: public SimpleShaderRenderer
229
	{
230
		const static std::string vss;
231
		const static std::string fss;
232
	public:
233
		AmbientOcclusionRenderer(const HMesh::Manifold& m, bool smooth, HMesh::VertexAttributeVector<double>& field, double max_val);
234
	};
235
 
236
 
237
/** Line fields are rendered by convolving a noise function in the direction of the line.
238
	This is useful, for instance, for curvature rendering. */
239
class LineFieldRenderer: public SimpleShaderRenderer
240
	{
241
		const static std::string vss;
242
		const static std::string fss;
243
		float r;
244
	public:
566 jab 245
		LineFieldRenderer(const HMesh::Manifold& m, bool smooth, HMesh::VertexAttributeVector<CGLA::Vec3d>& lines, float _r);
557 jab 246
		void draw();
247
	};
248
 
249
/** Class for wireframe rendering. Enable it will case all triangles to be drawn to be drawn as
250
 wireframe. Only triangles are supported, but it is fast. */
251
class DualVertexRenderer: public ManifoldRenderer
252
	{
253
		const static std::string vss;
254
		const static std::string gss;
255
		const static std::string fss;
256
	public:
257
		/// The constructor creates the wireframe shader program. It is static so the program is shared.
258
		DualVertexRenderer(const HMesh::Manifold& m, HMesh::VertexAttributeVector<CGLA::Vec4d>& field);
259
	};
260
}
261
 
262
#endif