Subversion Repositories gelsvn

Rev

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

Rev Author Line No. Line
594 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
 * ----------------------------------------------------------------------- */
6
 
601 jab 7
#include "../GL/glew.h"
396 jab 8
 
601 jab 9
#include "../CGLA/Mat4x4f.h"
10
#include "../CGLA/Vec3d.h"
11
#include "../HMesh/Manifold.h"
594 jab 12
 
167 jab 13
#include "draw.h"
396 jab 14
#include "SinglePassWireframeRenderer.h"
15
#include "IDBufferWireFrameRenderer.h"
441 jab 16
#include "SOIL.h"
396 jab 17
 
299 jrf 18
namespace GLGraphics
19
{
594 jab 20
    using namespace CGLA;
21
    using namespace HMesh;
22
    using namespace std;
23
 
24
    namespace
25
    {
26
        void set_material(const Geometry::Material& material)
27
        {
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
 
608 jrf 37
            glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, material.ambient);
38
            glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material.diffuse);
39
            glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material.specular);
594 jab 40
            glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material.shininess);
41
        }
42
    }
43
 
44
    void draw(const Geometry::IndexedFaceSet& geometry)
45
    {
46
        glBegin(GL_TRIANGLES);
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));
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
    {
64
        int old_mat_idx = -1;
65
        glBegin(GL_TRIANGLES);
66
        for(int i=0;i<tm.geometry.no_faces();i++)
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]]);
73
                glBegin(GL_TRIANGLES);
74
                old_mat_idx = new_mat_idx;
75
            }
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
 
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));
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]);
101
                glVertex3fv(vert.get());
102
            }
103
        }
104
        glEnd();
105
        glDisable(GL_TEXTURE_2D);
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
        }
119
    }
432 jab 120
 
492 jrf 121
	/// Draw an object of type T which contains only triangles as wireframe. In practice T = Manifold or TriMesh.
122
	template<typename T>
594 jab 123
    void draw_triangles_in_wireframe(T& m, bool per_vertex_norms, const CGLA::Vec3f& line_color)
492 jrf 124
	{
125
		static SinglePassWireframeRenderer swr;
126
		swr.enable(line_color);
127
		draw(m, per_vertex_norms);
128
		swr.disable();
129
	}
594 jab 130
 
492 jrf 131
	template
594 jab 132
    void draw_triangles_in_wireframe(HMesh::Manifold& m, bool per_vertex_norms, const CGLA::Vec3f& line_color);
133
 
492 jrf 134
	template
594 jab 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
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
 
191
 
192
 
193
    void draw(const Geometry::AABox& box)
194
    {
195
        glBegin(GL_QUADS);
196
        Vec3f norm_neg[] = {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)};
198
        for(int j=0;j<3;++j)
199
        {
200
            glNormal3fv(norm_neg[j].get());
201
            Vec3f p = box.get_pmin();
202
            glVertex3f(p[0], p[1], p[2]);
203
            p[(j+1)%3] = box.get_pmax()[(j+1)%3];
204
            glVertex3f(p[0], p[1], p[2]);
205
            p[j] = box.get_pmax()[j];
206
            glVertex3f(p[0], p[1], p[2]);
207
            p[(j+1)%3] = box.get_pmin()[(j+1)%3];
208
            glVertex3f(p[0], p[1], p[2]);
209
        }
210
        glEnd();
211
        glBegin(GL_QUADS);
212
        for(int j=0;j<3;++j)
213
        {
214
            glNormal3fv(norm_pos[j].get());
215
            Vec3f p = box.get_pmax();
216
            glVertex3f(p[0], p[1], p[2]);
217
            p[j] = box.get_pmin()[j];
218
            glVertex3f(p[0], p[1], p[2]);
219
            p[(j+1)%3] = box.get_pmin()[(j+1)%3];
220
            glVertex3f(p[0], p[1], p[2]);
221
            p[j] = box.get_pmax()[j];
222
            glVertex3f(p[0], p[1], p[2]);
223
        }
224
        glEnd();
225
    }
226
 
227
    void draw(const Geometry::OBox& box)
228
    {
229
        Mat4x4f m = identity_Mat4x4f();
230
        copy_matrix(box.get_rotation(), m);
231
        glPushMatrix();
232
        glMultMatrixf(m.get());
233
        draw(box.get_aabox());
234
        glPopMatrix();
235
    }
236
 
237
    /** Draw the tree. The first argument is the level counter, the second
238
     argument is the level at which to stop drawing. */
239
    template <class BoxType>
240
    void draw(const Geometry::BoundingINode<BoxType>& node, int level, int max_level)
241
    {
242
        if(level == max_level)
243
        {
244
            draw(node);
245
            return;
246
        }
247
        node->left->draw(level + 1, max_level);
248
        node->right->draw(level + 1, max_level);
249
    }
250
 
251
    template <class BoxType>
252
    void draw(const Geometry::BoundingLNode<BoxType>& node, int level, int max_level)
253
    {
299 jrf 254
#if USE_LEAF_BOXES
594 jab 255
        draw(node); 
299 jrf 256
#endif
594 jab 257
    }
258
 
259
    template <class BoxType>
260
    void draw(const Geometry::BoundingTree<BoxType>& tree, int max_level)
261
    {
262
        draw(*tree.root, 0, max_level);
263
    }
299 jrf 264
}