Subversion Repositories gelsvn

Rev

Rev 492 | Rev 601 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 492 Rev 594
Line -... Line 1...
-
 
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
 
1
#include <GL/glew.h>
7
#include <GL/glew.h>
2
 
8
 
3
#include "CGLA/Mat4x4f.h"
9
#include <CGLA/Mat4x4f.h>
4
#include "CGLA/Vec3d.h"
10
#include <CGLA/Vec3d.h>
5
#include "draw.h"
-
 
6
#include "HMesh/FaceCirculator.h"
11
#include <HMesh/Manifold.h>
7
 
12
 
-
 
13
#include "draw.h"
8
#include "SinglePassWireframeRenderer.h"
14
#include "SinglePassWireframeRenderer.h"
9
#include "IDBufferWireFrameRenderer.h"
15
#include "IDBufferWireFrameRenderer.h"
10
#include "SOIL.h"
16
#include "SOIL.h"
11
 
17
 
12
using namespace CGLA;
-
 
13
using namespace HMesh;
-
 
14
using namespace std;
-
 
15
 
-
 
16
namespace 
-
 
17
{
-
 
18
	void set_material(const Geometry::Material& material)
-
 
19
	{
-
 
20
		if(material.has_texture && material.tex_id >=0)
-
 
21
		{
-
 
22
			glEnable(GL_TEXTURE_2D);
-
 
23
			glBindTexture(GL_TEXTURE_2D, material.tex_id);
-
 
24
			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-
 
25
		}
-
 
26
		else
-
 
27
			glDisable(GL_TEXTURE_2D);
-
 
28
		
-
 
29
		glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, material.ambient);
-
 
30
		glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material.diffuse);
-
 
31
		glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material.specular);
-
 
32
		glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material.shininess);
-
 
33
	}
-
 
34
	
-
 
35
}
-
 
36
 
-
 
37
namespace GLGraphics
18
namespace GLGraphics
38
{
19
{
-
 
20
    using namespace CGLA;
-
 
21
    using namespace HMesh;
-
 
22
    using namespace std;
39
	
23
    
-
 
24
    namespace
-
 
25
    {
-
 
26
        void set_material(const Geometry::Material& material)
-
 
27
        {
40
	void draw(Manifold& m, bool per_vertex_norms)
28
            if(material.has_texture && material.tex_id >=0)
-
 
29
            {
-
 
30
                glEnable(GL_TEXTURE_2D);
-
 
31
                glBindTexture(GL_TEXTURE_2D, material.tex_id);
-
 
32
                glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-
 
33
            }
-
 
34
            else
-
 
35
                glDisable(GL_TEXTURE_2D);
-
 
36
            
-
 
37
            glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, Vec4f(material.ambient).get());
-
 
38
            glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, Vec4f(material.diffuse).get());
-
 
39
            glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, Vec4f(material.specular).get());
-
 
40
            glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material.shininess);
-
 
41
        }
-
 
42
    }
41
	{
43
    
42
		for(FaceIter f=m.faces_begin(); f != m.faces_end(); ++f)
44
    void draw(const Geometry::IndexedFaceSet& geometry)
43
		{
45
    {
44
			FaceCirculator fc(f);
46
        glBegin(GL_TRIANGLES);
45
			if(!per_vertex_norms) 
47
        for(int i=0;i<geometry.no_faces();i++)
-
 
48
        {
-
 
49
            Vec3i g_face = geometry.face(i);
-
 
50
            Vec3f vert0 = geometry.vertex(g_face[0]);
-
 
51
            Vec3f vert1 = geometry.vertex(g_face[1]);
-
 
52
            Vec3f vert2 = geometry.vertex(g_face[2]);
-
 
53
            Vec3f norm = normalize(cross(vert1-vert0, vert2-vert0));
46
				glNormal3fv(normal(f).get());
54
            glNormal3fv(norm.get());
-
 
55
            glVertex3fv(vert0.get());
-
 
56
            glVertex3fv(vert1.get());
-
 
57
            glVertex3fv(vert2.get());
-
 
58
        }
-
 
59
        glEnd();
-
 
60
    }
-
 
61
    
-
 
62
    void draw(const Geometry::TriMesh& tm, bool per_vertex_norms)
-
 
63
    {
47
			if(no_edges(f)== 3) 
64
        int old_mat_idx = -1;
48
				glBegin(GL_TRIANGLES);
65
        glBegin(GL_TRIANGLES);
-
 
66
        for(int i=0;i<tm.geometry.no_faces();i++)
49
			else 
67
        {
-
 
68
            int new_mat_idx = i<static_cast<int>(tm.mat_idx.size()) ? tm.mat_idx[i] : -1;
-
 
69
            if(new_mat_idx != old_mat_idx)
-
 
70
            {
-
 
71
                glEnd();
-
 
72
                set_material(tm.materials[tm.mat_idx[i]]);
50
				glBegin(GL_POLYGON);
73
                glBegin(GL_TRIANGLES);
51
			while(!fc.end())
74
                old_mat_idx = new_mat_idx;
52
			{
75
            }
53
				Vec3f n = normal(fc.get_vertex());
76
            Vec3i n_face = tm.normals.face(i);
-
 
77
            Vec3i g_face = tm.geometry.face(i);
-
 
78
            Vec3i t_face = tm.texcoords.face(i);
-
 
79
            
54
				if(per_vertex_norms) 
80
            if(!per_vertex_norms)
-
 
81
            {
-
 
82
                Vec3f vert0 = tm.geometry.vertex(g_face[0]);
-
 
83
                Vec3f vert1 = tm.geometry.vertex(g_face[1]);
-
 
84
                Vec3f vert2 = tm.geometry.vertex(g_face[2]);
-
 
85
                Vec3f norm = normalize(cross(vert1-vert0, vert2-vert0));
55
					glNormal3fv(n.get());
86
                glNormal3fv(norm.get());
-
 
87
            }
-
 
88
            for(int j=0;j<3;j++)
-
 
89
            {
-
 
90
                if(per_vertex_norms && n_face != Geometry::NULL_FACE)
-
 
91
                {
-
 
92
                    Vec3f norm = tm.normals.vertex(n_face[j]);
-
 
93
                    glNormal3fv(norm.get());
-
 
94
                }
-
 
95
                if(t_face != Geometry::NULL_FACE)
-
 
96
                {
-
 
97
                    Vec3f texc = tm.texcoords.vertex(t_face[j]);
-
 
98
                    glTexCoord2fv(texc.get());
-
 
99
                }
-
 
100
                Vec3f vert = tm.geometry.vertex(g_face[j]);
56
				glVertex3fv(fc.get_vertex()->pos.get());
101
                glVertex3fv(vert.get());
57
				++fc;
102
            }
58
			}
103
        }
59
			glEnd();
104
        glEnd();
-
 
105
        glDisable(GL_TEXTURE_2D);
60
		}
106
    }
-
 
107
    
-
 
108
    void load_textures(Geometry::TriMesh& tm)
-
 
109
    {
-
 
110
        for(unsigned int i=0;i<tm.materials.size(); ++i)
-
 
111
        {
-
 
112
            Geometry::Material& mat = tm.materials[i];
-
 
113
            if(mat.tex_name != "")
-
 
114
            {
-
 
115
                string name = mat.tex_path + mat.tex_name;
-
 
116
                mat.tex_id = SOIL_load_OGL_texture(name.data(), 0, 0, SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_POWER_OF_TWO);
-
 
117
            }
-
 
118
        }
61
	}
119
    }
62
 
120
 
63
	void draw(const Geometry::IndexedFaceSet& geometry)
-
 
64
	{
-
 
65
		glBegin(GL_TRIANGLES);
-
 
66
		for(int i=0;i<geometry.no_faces();i++)
-
 
67
		{
-
 
68
				Vec3i g_face = geometry.face(i);
-
 
69
				Vec3f vert0 = geometry.vertex(g_face[0]);
-
 
70
				Vec3f vert1 = geometry.vertex(g_face[1]);
-
 
71
				Vec3f vert2 = geometry.vertex(g_face[2]);
-
 
72
				Vec3f norm = normalize(cross(vert1-vert0, vert2-vert0));
-
 
73
				glNormal3fv(norm.get());
-
 
74
				glVertex3fv(vert0.get());
-
 
75
				glVertex3fv(vert1.get());
-
 
76
				glVertex3fv(vert2.get());
-
 
77
		}
-
 
78
		glEnd();
-
 
79
	}
-
 
80
	
-
 
81
	void draw(const Geometry::TriMesh& tm, bool per_vertex_norms)
-
 
82
	{
-
 
83
		int old_mat_idx = -1;
-
 
84
		glBegin(GL_TRIANGLES);
-
 
85
		for(int i=0;i<tm.geometry.no_faces();i++)
-
 
86
		{
-
 
87
			int new_mat_idx = i<static_cast<int>(tm.mat_idx.size()) ? tm.mat_idx[i] : -1;
-
 
88
			if(new_mat_idx != old_mat_idx)
-
 
89
			{
-
 
90
				glEnd();
-
 
91
				set_material(tm.materials[tm.mat_idx[i]]);
-
 
92
				glBegin(GL_TRIANGLES);
-
 
93
				old_mat_idx = new_mat_idx;
-
 
94
			}
-
 
95
			Vec3i n_face = tm.normals.face(i);
-
 
96
			Vec3i g_face = tm.geometry.face(i);
-
 
97
			Vec3i t_face = tm.texcoords.face(i);
-
 
98
			
-
 
99
			if(!per_vertex_norms)
-
 
100
			{
-
 
101
				Vec3f vert0 = tm.geometry.vertex(g_face[0]);
-
 
102
				Vec3f vert1 = tm.geometry.vertex(g_face[1]);
-
 
103
				Vec3f vert2 = tm.geometry.vertex(g_face[2]);
-
 
104
				Vec3f norm = normalize(cross(vert1-vert0, vert2-vert0));
-
 
105
				glNormal3fv(norm.get());
-
 
106
			}
-
 
107
			for(int j=0;j<3;j++)
-
 
108
			{
-
 
109
				if(per_vertex_norms && n_face != Geometry::NULL_FACE)
-
 
110
				{
-
 
111
					Vec3f norm = tm.normals.vertex(n_face[j]);
-
 
112
					glNormal3fv(norm.get());
-
 
113
				}
-
 
114
				if(t_face != Geometry::NULL_FACE)
-
 
115
				{
-
 
116
					Vec3f texc = tm.texcoords.vertex(t_face[j]);
-
 
117
					glTexCoord2fv(texc.get());
-
 
118
				}
-
 
119
				Vec3f vert = tm.geometry.vertex(g_face[j]);
-
 
120
				glVertex3fv(vert.get());
-
 
121
			}
-
 
122
		}
-
 
123
		glEnd();
-
 
124
		glDisable(GL_TEXTURE_2D);
-
 
125
	}
-
 
126
	
-
 
127
	void load_textures(Geometry::TriMesh& tm)
-
 
128
	{
-
 
129
		for(unsigned int i=0;i<tm.materials.size(); ++i)
-
 
130
		{
-
 
131
			Geometry::Material& mat = tm.materials[i];
-
 
132
			if(mat.tex_name != "")
-
 
133
			{
-
 
134
				string name = mat.tex_path + mat.tex_name;
-
 
135
				mat.tex_id = SOIL_load_OGL_texture(name.data(), 0, 0, SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_POWER_OF_TWO);
-
 
136
			}
-
 
137
		}
-
 
138
	}
-
 
139
	 
-
 
140
	/// Draw an object of type T which contains only triangles as wireframe. In practice T = Manifold or TriMesh.
121
	/// Draw an object of type T which contains only triangles as wireframe. In practice T = Manifold or TriMesh.
141
	template<typename T>
122
	template<typename T>
142
	inline void draw_triangles_in_wireframe(T& m, bool per_vertex_norms, const CGLA::Vec3f& line_color)
123
    void draw_triangles_in_wireframe(T& m, bool per_vertex_norms, const CGLA::Vec3f& line_color)
143
	{
124
	{
144
		static SinglePassWireframeRenderer swr;
125
		static SinglePassWireframeRenderer swr;
145
		swr.enable(line_color);
126
		swr.enable(line_color);
146
		draw(m, per_vertex_norms);
127
		draw(m, per_vertex_norms);
147
		swr.disable();
128
		swr.disable();
148
	}
129
	}
149
 
-
 
150
	template
-
 
151
	inline void draw_triangles_in_wireframe(HMesh::Manifold& m, bool per_vertex_norms, const CGLA::Vec3f& line_color);
-
 
152
 
-
 
153
	template
-
 
154
	inline void draw_triangles_in_wireframe(Geometry::TriMesh& m, bool per_vertex_norms, const CGLA::Vec3f& line_color);
-
 
155
 
-
 
156
  template<class T>
-
 
157
	void draw_wireframe_oldfashioned(T& m, bool per_vertex_norms, const Vec3f& line_color)
-
 
158
	{
130
    
159
		// Store state that we change
-
 
160
		glPushAttrib(GL_POLYGON_BIT);
-
 
161
		GLboolean lights_on;
-
 
162
		glGetBooleanv(GL_LIGHTING, &lights_on);
-
 
163
		Vec4f current_color;
-
 
164
		glGetFloatv(GL_CURRENT_COLOR, &current_color[0]);
-
 
165
		
-
 
166
		// Draw filled
-
 
167
		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-
 
168
		draw(m, per_vertex_norms);
-
 
169
		
-
 
170
		// Draw lines
-
 
171
		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-
 
172
		glDisable(GL_LIGHTING);
-
 
173
		glEnable(GL_POLYGON_OFFSET_LINE);
-
 
174
		glPolygonOffset(0,-5);
-
 
175
		glColor3fv(line_color.get());
-
 
176
		draw(m, per_vertex_norms);
-
 
177
		
-
 
178
		// Put back old state
-
 
179
		glColor3fv(current_color.get());
-
 
180
		if(lights_on) glEnable(GL_LIGHTING);
-
 
181
		glPopAttrib();
-
 
182
	}
-
 
183
	
-
 
184
	template
131
	template
185
	void draw_wireframe_oldfashioned<HMesh::Manifold>(HMesh::Manifold& m, bool per_vertex_norms, const Vec3f& line_color);
132
    void draw_triangles_in_wireframe(HMesh::Manifold& m, bool per_vertex_norms, const CGLA::Vec3f& line_color);
186
 
133
    
187
	template
134
	template
-
 
135
    void draw_triangles_in_wireframe(Geometry::TriMesh& m, bool per_vertex_norms, const CGLA::Vec3f& line_color);
-
 
136
    
-
 
137
    template<class T>
-
 
138
    void draw_wireframe_oldfashioned(const T& m, bool per_vertex_norms, const Vec3f& line_color)
-
 
139
    {
-
 
140
        // Store state that we change
-
 
141
        glPushAttrib(GL_POLYGON_BIT);
-
 
142
        GLboolean lights_on;
-
 
143
        glGetBooleanv(GL_LIGHTING, &lights_on);
-
 
144
        Vec4f current_color;
-
 
145
        glGetFloatv(GL_CURRENT_COLOR, &current_color[0]);
-
 
146
        
-
 
147
        // Draw filled
-
 
148
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-
 
149
        draw(m, per_vertex_norms);
-
 
150
        
-
 
151
        // Draw lines
-
 
152
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-
 
153
        glDisable(GL_LIGHTING);
-
 
154
        glEnable(GL_POLYGON_OFFSET_LINE);
-
 
155
        glPolygonOffset(0,-5);
-
 
156
        glColor3fv(line_color.get());
-
 
157
        draw(m, per_vertex_norms);
-
 
158
        
-
 
159
        // Put back old state
-
 
160
        glColor3fv(current_color.get());
-
 
161
        if(lights_on) glEnable(GL_LIGHTING);
-
 
162
        glPopAttrib();
-
 
163
    }
-
 
164
    template
-
 
165
    void draw_wireframe_oldfashioned(const HMesh::Manifold& m, bool per_vertex_norms, const Vec3f& line_color);
-
 
166
    
-
 
167
    template
188
	void draw_wireframe_oldfashioned(Geometry::TriMesh& m, bool per_vertex_norms, const Vec3f& line_color);
168
    void draw_wireframe_oldfashioned(const Geometry::TriMesh& m, bool per_vertex_norms, const Vec3f& line_color);
-
 
169
    
-
 
170
    
-
 
171
    void draw(const Manifold& m, bool per_vertex_norms)
-
 
172
    {
-
 
173
        for(FaceIDIterator f = m.faces_begin(); f != m.faces_end(); ++f){
-
 
174
            if(!per_vertex_norms)
-
 
175
                glNormal3dv(normal(m, *f).get());
-
 
176
            if(no_edges(m, *f)== 3)
-
 
177
                glBegin(GL_TRIANGLES);
-
 
178
            else
-
 
179
                glBegin(GL_POLYGON);
-
 
180
            
-
 
181
            for(Walker w = m.walker(*f); !w.full_circle(); w = w.circulate_face_ccw()){
-
 
182
                Vec3d n = normal(m, w.vertex());
-
 
183
                if(per_vertex_norms)
-
 
184
                    glNormal3dv(n.get());
-
 
185
                glVertex3dv(m.pos(w.vertex()).get());
-
 
186
            }
-
 
187
            glEnd();
-
 
188
        }
-
 
189
    }
-
 
190
    
189
 
191
    
190
	
192
    
191
	void draw(const Geometry::AABox& box)
193
    void draw(const Geometry::AABox& box)
192
	{
194
    {
193
		glBegin(GL_QUADS);
195
        glBegin(GL_QUADS);
194
		Vec3f norm_neg[] = {Vec3f(0,0,-1), Vec3f(-1,0,0), Vec3f(0,-1,0)};
196
        Vec3f norm_neg[] = {Vec3f(0,0,-1), Vec3f(-1,0,0), Vec3f(0,-1,0)};
195
		Vec3f norm_pos[] = {Vec3f(0,0, 1), Vec3f( 1,0,0), Vec3f(0, 1,0)};
197
        Vec3f norm_pos[] = {Vec3f(0,0, 1), Vec3f( 1,0,0), Vec3f(0, 1,0)};
196
		for(int j=0;j<3;++j)
198
        for(int j=0;j<3;++j)
197
		{
199
        {
198
			glNormal3fv(norm_neg[j].get());
200
            glNormal3fv(norm_neg[j].get());
199
			Vec3f p = box.get_pmin();
201
            Vec3f p = box.get_pmin();
200
			glVertex3f(p[0], p[1], p[2]);
202
            glVertex3f(p[0], p[1], p[2]);
201
			p[(j+1)%3] = box.get_pmax()[(j+1)%3];
203
            p[(j+1)%3] = box.get_pmax()[(j+1)%3];
202
			glVertex3f(p[0], p[1], p[2]);
204
            glVertex3f(p[0], p[1], p[2]);
203
			p[j] = box.get_pmax()[j];
205
            p[j] = box.get_pmax()[j];
204
			glVertex3f(p[0], p[1], p[2]);
206
            glVertex3f(p[0], p[1], p[2]);
205
			p[(j+1)%3] = box.get_pmin()[(j+1)%3];
207
            p[(j+1)%3] = box.get_pmin()[(j+1)%3];
206
			glVertex3f(p[0], p[1], p[2]);
208
            glVertex3f(p[0], p[1], p[2]);
207
		}
209
        }
208
		glEnd();
210
        glEnd();
209
		glBegin(GL_QUADS);
211
        glBegin(GL_QUADS);
210
		for(int j=0;j<3;++j)
212
        for(int j=0;j<3;++j)
211
		{
213
        {
212
			glNormal3fv(norm_pos[j].get());
214
            glNormal3fv(norm_pos[j].get());
213
			Vec3f p = box.get_pmax();
215
            Vec3f p = box.get_pmax();
214
			glVertex3f(p[0], p[1], p[2]);
216
            glVertex3f(p[0], p[1], p[2]);
215
			p[j] = box.get_pmin()[j];
217
            p[j] = box.get_pmin()[j];
216
			glVertex3f(p[0], p[1], p[2]);
218
            glVertex3f(p[0], p[1], p[2]);
217
			p[(j+1)%3] = box.get_pmin()[(j+1)%3];
219
            p[(j+1)%3] = box.get_pmin()[(j+1)%3];
218
			glVertex3f(p[0], p[1], p[2]);
220
            glVertex3f(p[0], p[1], p[2]);
219
			p[j] = box.get_pmax()[j];
221
            p[j] = box.get_pmax()[j];
220
			glVertex3f(p[0], p[1], p[2]);
222
            glVertex3f(p[0], p[1], p[2]);
221
		}
223
        }
222
		glEnd();
224
        glEnd();
223
	}
225
    }
224
	
226
    
225
	void draw(const Geometry::OBox& box)
227
    void draw(const Geometry::OBox& box)
226
	{
228
    {
227
		Mat4x4f m = identity_Mat4x4f();
229
        Mat4x4f m = identity_Mat4x4f();
228
		copy_matrix(box.get_rotation(), m);
230
        copy_matrix(box.get_rotation(), m);
229
		glPushMatrix();
231
        glPushMatrix();
230
		glMultMatrixf(m.get());
232
        glMultMatrixf(m.get());
231
		draw(box.get_aabox());
233
        draw(box.get_aabox());
232
		glPopMatrix();
234
        glPopMatrix();
233
	}
235
    }
234
	
236
    
235
	/** Draw the tree. The first argument is the level counter, the second
237
    /** Draw the tree. The first argument is the level counter, the second
236
	 argument is the level at which to stop drawing. */
238
     argument is the level at which to stop drawing. */
237
	template <class BoxType>
239
    template <class BoxType>
238
	void draw(const Geometry::BoundingINode<BoxType>& node, int level, int max_level)
240
    void draw(const Geometry::BoundingINode<BoxType>& node, int level, int max_level)
239
	{
241
    {
240
		if(level == max_level)
242
        if(level == max_level)
241
		{
243
        {
242
			draw(node); 
244
            draw(node);
243
			return;
245
            return;
244
		}
246
        }
245
		node->left->draw(level + 1, max_level);
247
        node->left->draw(level + 1, max_level);
246
		node->right->draw(level + 1, max_level);  
248
        node->right->draw(level + 1, max_level);
247
	}
249
    }
248
	
250
    
249
	template <class BoxType>
251
    template <class BoxType>
250
	void draw(const Geometry::BoundingLNode<BoxType>& node, int level, int max_level)
252
    void draw(const Geometry::BoundingLNode<BoxType>& node, int level, int max_level)
251
	{
253
    {
252
#if USE_LEAF_BOXES
254
#if USE_LEAF_BOXES
253
		draw(node); 
255
        draw(node); 
254
#endif
256
#endif
255
	}
257
    }
256
	
258
    
257
	template <class BoxType>
259
    template <class BoxType>
258
	void draw(const Geometry::BoundingTree<BoxType>& tree, int max_level)
260
    void draw(const Geometry::BoundingTree<BoxType>& tree, int max_level)
259
	{
261
    {
260
		draw(*tree.root, 0, max_level);
262
        draw(*tree.root, 0, max_level);
261
	}
263
    }
262
}
264
}