Subversion Repositories gelsvn

Rev

Details | Last modification | View Log | RSS feed

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