Subversion Repositories gelsvn

Rev

Rev 566 | Go to most recent revision | Details | Last modification | View Log | RSS feed

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